specialization of template.... in different namespace的解决

本文解决了一个关于C++模板特化在不同命名空间内的编译错误问题,通过使用继承的方式进行了有效的修正。

代码来自DTL文档index.htm

struct Example
{                                    // tablename.columnname:
	int exampleInt;                 // DB_EXAMPLE.INT_VALUE
	string exampleStr;              // DB_EXAMPLE.STRING_VALUE
	double exampleDouble;           // DB_EXAMPLE.DOUBLE_VALUE
	long exampleLong;               // DB_EXAMPLE.EXAMPLE_LONG
	TIMESTAMP_STRUCT exampleDate;   // DB_EXAMPLE.EXAMPLE_DATE
};
这一段上次还碰到过TIMESTAMP_STRUCT未定义的情况,纯属意外

template<>class dtl::DefaultBCA<Example>
{
public:
    	void operator()(BoundIOs &cols, Example &rowbuf)
    	{
    		cols["INT_VALUE"] == rowbuf.exampleInt;
    		cols["STRING_VALUE"] == rowbuf.exampleStr;
    		cols["DOUBLE_VALUE"] == rowbuf.exampleDouble;
    		cols["EXAMPLE_LONG"] == rowbuf.exampleLong;
    		cols["EXAMPLE_DATE"] == rowbuf.exampleDate;
	}
};
在编译的时候,代码中只有个输出helloworld,错误提示如下:

error: specialization of ‘template<class DataObj> class dtl::DefaultBCA’ in different namespace

参考1:http://womble.decadent.org.uk/c++/template-faq.html#specialise-ns    faq,是个很和谐的东东啊

Q: Whatdoes the error message "specialization of ... in different namespace"mean?

A: Thismeans that the code appears to be defining a template specialisation, but itnames a template that was defined in a different namespace. This is not valid,though some older versions of g++ accept it. Every declaration for a templatemust be placed in the same namespace, just like repeated declarations of anyother named entity.


参考2:http://gcc.gnu.org/ml/gcc/2005-04/msg00134.html 

The error is that the specialisation isin a different namespace from  the declaration, not the definition.   

//他的观点是声明与模板的具体化在不同的命名空间了


先不去深究,直接上楼主的解决方案:

修改具体化代码

template<> class DefaultBCA<Example>

为:

class Test:public DefaultBCA<Example>

即具体化模板类的时候,用类继承


注意点:

1)      template<>,也可以写在class那行的第二行,如果没有,也许会导致too few template-parameter-lists的错误;可以参考

http://hi.baidu.com/huangyunict/blog/item/5b50bdd658b8f32206088bd5.html

参考http://forum.ubuntu.org.cn/post-99237.html ,貌似是gcc版本的问题

2)      这里为什么要用继承,我也不知道,只是改了之后编译能过,起码先没错。



说明下:

        这是楼主经过查找和测试之后改的,由于对模板不是很熟,所以也搜了部分基础的东东,就没贴上来,其他主要参考的链接都给出了,应该够具体了。希望对以后有同样问题的人有用,不过只是对楼主自己遇到的情况而言,不保证其他情况。


#ifndef H_6B9572DA_A64B_49E6_B234_051480991C89 #define H_6B9572DA_A64B_49E6_B234_051480991C89 #ifndef __cplusplus # error "It's not going to compile without a C++ compiler..." #endif #if defined(BACKWARD_CXX11) #elif defined(BACKWARD_CXX98) #else # if __cplusplus >= 201103L # define BACKWARD_CXX11 # define BACKWARD_ATLEAST_CXX11 # define BACKWARD_ATLEAST_CXX98 # else # define BACKWARD_CXX98 # define BACKWARD_ATLEAST_CXX98 # endif #endif // You can define one of the following (or leave it to the auto-detection): // // #define BACKWARD_SYSTEM_LINUX // - specialization for linux // // #define BACKWARD_SYSTEM_UNKNOWN // - placebo implementation, does nothing. // #if defined(BACKWARD_SYSTEM_LINUX) #elif defined(BACKWARD_SYSTEM_UNKNOWN) #else # if defined(__linux) # define BACKWARD_SYSTEM_LINUX # else # define BACKWARD_SYSTEM_UNKNOWN # endif #endif #include <fstream> #include <iostream> #include <algorithm> #include <cstdlib> #include <cstdio> #include <cstring> #include <cctype> #include <string> #include <new> #include <iomanip> #include <vector> #if defined(BACKWARD_SYSTEM_LINUX) // On linux, backtrace can back-trace or "walk" the stack using the following // libraries: // // #define BACKWARD_HAS_UNWIND 1 // - unwind comes from libgcc, but I saw an equivalent inside clang itself. // - with unwind, the stacktrace is as accurate as it can possibly be, since // this is used by the C++ runtine in gcc/clang for stack unwinding on // exception. // - normally libgcc is already linked to your program by default. // // #define BACKWARD_HAS_BACKTRACE == 1 // - backtrace seems to be a little bit more portable than libunwind, but on // linux, it uses unwind anyway, but abstract away a tiny information that is // sadly really important in order to get perfectly accurate stack traces. // - backtrace is part of the (e)glib library. // // The default is: // #define BACKWARD_HAS_UNWIND == 1 // // Note that only one of the define should be set to 1 at a time. // # if BACKWARD_HAS_UNWIND == 1 # elif BACKWARD_HAS_BACKTRACE == 1 # else # undef BACKWARD_HAS_UNWIND # define BACKWARD_HAS_UNWIND 1 # undef BACKWARD_HAS_BACKTRACE # define BACKWARD_HAS_BACKTRACE 0 # endif // On linux, backward can extract detailed information about a stack trace // using one of the following libraries: // // #define BACKWARD_HAS_DW 1 // - libdw gives you the most juicy details out of your stack traces: // - object filename // - function name // - source filename // - line and column numbers // - source code snippet (assuming the file is accessible) // - variables name and values (if not optimized out) // - You need to link with the lib "dw": // - apt-get install libdw-dev // - g++/clang++ -ldw ... // // #define BACKWARD_HAS_BFD 1 // - With libbfd, you get a fair amount of details: // - object filename // - function name // - source filename // - line numbers // - source code snippet (assuming the file is accessible) // - You need to link with the lib "bfd": // - apt-get install binutils-dev // - g++/clang++ -lbfd ... // // #define BACKWARD_HAS_BACKTRACE_SYMBOL 1 // - backtrace provides minimal details for a stack trace: // - object filename // - function name // - backtrace is part of the (e)glib library. // // The default is: // #define BACKWARD_HAS_BACKTRACE_SYMBOL == 1 // // Note that only one of the define should be set to 1 at a time. // # if BACKWARD_HAS_DW == 1 # elif BACKWARD_HAS_BFD == 1 # elif BACKWARD_HAS_BACKTRACE_SYMBOL == 1 # else # undef BACKWARD_HAS_DW # define BACKWARD_HAS_DW 0 # undef BACKWARD_HAS_BFD # define BACKWARD_HAS_BFD 0 # undef BACKWARD_HAS_BACKTRACE_SYMBOL # define BACKWARD_HAS_BACKTRACE_SYMBOL 1 # endif # if BACKWARD_HAS_UNWIND == 1 # include <unwind.h> // while gcc's unwind.h defines something like that: // extern _Unwind_Ptr _Unwind_GetIP (struct _Unwind_Context *); // extern _Unwind_Ptr _Unwind_GetIPInfo (struct _Unwind_Context *, int *); // // clang's unwind.h defines something like this: // uintptr_t _Unwind_GetIP(struct _Unwind_Context* __context); // // Even if the _Unwind_GetIPInfo can be linked to, it is not declared, worse we // cannot just redeclare it because clang's unwind.h doesn't define _Unwind_Ptr // anyway. // // Luckily we can play on the fact that the guard macros have a different name: #ifdef __CLANG_UNWIND_H // In fact, this function still comes from libgcc (on my different linux boxes, // clang links against libgcc). # include <inttypes.h> extern "C" uintptr_t _Unwind_GetIPInfo(_Unwind_Context*, int*); #endif # endif # include <cxxabi.h> # include <fcntl.h> # include <link.h> # include <sys/stat.h> # include <syscall.h> # include <unistd.h> # include <signal.h> # if BACKWARD_HAS_BFD == 1 // NOTE: defining PACKAGE{,_VERSION} is required before including // bfd.h on some platforms, see also: // https://sourceware.org/bugzilla/show_bug.cgi?id=14243 # ifndef PACKAGE # define PACKAGE # endif # ifndef PACKAGE_VERSION # define PACKAGE_VERSION # endif # include <bfd.h> # ifndef _GNU_SOURCE # define _GNU_SOURCE # include <dlfcn.h> # undef _GNU_SOURCE # else # include <dlfcn.h> # endif # endif # if BACKWARD_HAS_DW == 1 # include <elfutils/libdw.h> # include <elfutils/libdwfl.h> # include <dwarf.h> # endif # if (BACKWARD_HAS_BACKTRACE == 1) || (BACKWARD_HAS_BACKTRACE_SYMBOL == 1) // then we shall rely on backtrace # include <execinfo.h> # endif #endif // defined(BACKWARD_SYSTEM_LINUX) #ifdef BACKWARD_ATLEAST_CXX11 # include <unordered_map> # include <utility> // for std::swap namespace backward { namespace details { template <typename K, typename V> struct hashtable { typedef std::unordered_map<K, V> type; }; using std::move; } // namespace details } // namespace backward #else // NOT BACKWARD_ATLEAST_CXX11 # include <map> namespace backward { namespace details { template <typename K, typename V> struct hashtable { typedef std::map<K, V> type; }; template <typename T> const T& move(const T& v) { return v; } template <typename T> T& move(T& v) { return v; } } // namespace details } // namespace backward #endif // BACKWARD_ATLEAST_CXX11 namespace backward { namespace system_tag { struct linux_tag; // seems that I cannot call that "linux" because the name // is already defined... so I am adding _tag everywhere. struct unknown_tag; #if defined(BACKWARD_SYSTEM_LINUX) typedef linux_tag current_tag; #elif defined(BACKWARD_SYSTEM_UNKNOWN) typedef unknown_tag current_tag; #else # error "May I please get my system defines?" #endif } // namespace system_tag 注释上述代码
最新发布
09-29
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值