linux template error: explicit specialization in non-namespace scope
来源:互联网 发布:天天向上网络 编辑:程序博客网 时间:2024/05/18 02:19
上面的代码在Windows上编译、运行都没有问题,但是移植到linux上,编译时报错:namespace TestTemp
{
class CBase
{
public:
template <class R, class P1, class P2>
R UICall(const char *name, const P1 &p1, const P2 &p2)
{return CallMid<R>();
}
template <class R>
R CallMid()
{
R ret;
CallMe(ret);
return ret;
}
template <>
void CallMid<void>()
{
CallMe();
}
void CallMe(std::string &ret)
{
// do something
ret = "hello";
}......
void CallMe()
{
// do something
printf("void EndCall!\n");
}
};}
using namespace TestTemp;
int main()
{
CBase oBase;
oBase.UICall<void>("test", 1, 2);
string strT = oBase.UICall<std::string>("test", 1, 2);
printf("size=%llu, str=%s\n", strT.size(), strT.c_str());
return 0;
}
error: explicit specialization in non-namespace scope 'class TestTemp::CBase'
原因是下面的代码在非命名空间中显式特化:
template <>很显然,这里绕不过去,必须对void型显式特化(否则main函数编译时会报错:不能定义void型变量)。对大部分项目来说,修改这个问题很容易:只要把特化的代码写在类定义的外面(但要写在namespace下)就搞定了,如第一段代码应该写成这样:
void CallMid<void>()
{
CallMe();
}
namespace TestTemp
{
class CBase
{
public:
template <class R, class P1, class P2>
R UICall(const char *name, const P1 &p1, const P2 &p2)
{return CallMid<R>();
}
template <class R>
R CallMid()
{
R ret;
CallMe(ret);
return ret;
}
void CallMe(std::string &ret)
{
// do something
ret = "hello";
}......
void CallMe()
{
// do something
printf("void EndCall!\n");
}
};template <>
void CBase::CallMid<void>()
{
CallMe();
}}
using namespace TestTemp;
int main()
{
CBase oBase;
oBase.UICall<void>("test", 1, 2);
string strT = oBase.UICall<std::string>("test", 1, 2);
printf("size=%llu, str=%s\n", strT.size(), strT.c_str());
return 0;
}
上面的代码在VC和linux上都能顺利编过并运行。但是在我的项目中悲剧了:上面的代码是库代码,而且这是个头文件,真正的工程项目很多文件会include这个头文件,这样在工程项目链接时报错:CBase::CallMid<void> muti defined!你会想到把特化代码移到库的cpp文件中,这样不行,工程项目编译时就报错找不到声明;或者你又想到特化代码先在头文件中声明,实现放到cpp文件中,但还是不行,编译库代码时编译器又已经发现你explicit specialization in non-namespace scope的意图了...
好吧,你想到了偏特化,我增加一个无用的模板参数Dummy,然后将第一个模板参数R偏特化为void
可惜,在C++标准中,函数模板不能偏特化(linux同标准,windows上没有这个限制),偏特化对能对class、struct这种类型模板...template <class R, class Dummy>
网上查了资料,所幸还有下面两种方法都能解决问题:
第一种是用重载机制实现:
template <class R,class D>但是这种解法会造成未使用的复杂对象的构造和析构,产生额外的开销。所以最终使用下面的方法,完美的解决了问题:
R CallMid(D/*Dummy*/)
{
R ret;
CallMe(ret);
return ret;
}
template <class D>
void CallMid<void,D>(void)
{
CallMe();
}
namespace TestTemp
{template<typename T>
struct identity { typedef T type; };class CBase
{
public:
template <class R, class P1, class P2>
R UICall(const char *name, const P1 &p1, const P2 &p2)
{return CallMid<R>();
}
template <class R>
R CallMid()
{
return TCallType(identity<R>());
}template <class R>
R TCallType(identity<R>)
{
R ret;
CallMe(ret);
return ret;
}
void TCallType(identity<void>)
{
CallMe();
}
void CallMe(std::string &ret)
{
// do something
ret = "hello";
}......
void CallMe()
{
// do something
printf("void EndCall!\n");
}
};}
using namespace TestTemp;
int main()
{
CBase oBase;
oBase.UICall<void>("test", 1, 2);
string strT = oBase.UICall<std::string>("test", 1, 2);
printf("size=%llu, str=%s\n", strT.size(), strT.c_str());
return 0;
}
- linux template error: explicit specialization in non-namespace scope
- specialization of template.... in different namespace的解决
- specialization of template.... in different namespace的解决
- Template Specialization
- template specialization
- 安装caffe编译opencv3.0出现error: a storage class is not allowed in an explicit specialization问题
- Template Specialization and Partial Template Specialization
- (三)Jetson TK1安装opencv-2.4.9,可能的问题error: a storage class is not allowed in an explicit specialization
- 模板特殊化(Template specialization)
- template specialization on template class
- error: 'function' in namespace 'std' does not name a template type
- ros kinetic版编译error: ‘shared_ptr’ in namespace ‘std’ does not name a template type
- befriending a template in another namespace
- 模板特化(template specialization)
- C++ Template Specialization (模板特化)
- linux下 Qt 中 OpenGL error: not declared in this scope
- linux 编译ffmpeg 出错:error: 'UINT64_C' was not declared in this scope
- /usr/include/linux/netfilter_ipv4.h:53: error: ‘INT_MIN’ was not declared in this scope
- [转]linux strace命令
- JSP总结
- CentOS yum安装nginx
- linux CentOS 安装DDD调试器详解
- Windows 查询系统位数 32位还是64位
- linux template error: explicit specialization in non-namespace scope
- linux 安装subversion svn Option expected
- linux 为什么 没有生成core文件? 之二
- VS 2005 查找功能无法使用的解决办法 VS2005重新配置
- /etc/sysconfig/network: No such file or directory
- undefined reference to `SSL_get_current_cipher\' 链接OpenSSL库 -lssl
- svn 不显示图标状态
- Deep Learning(深度学习)学习笔记整理系列之(四)
- [转] std::_Copy_impl