我正在使用Boost.Serialization序列化带有折叠表达式的模板包:
template <typename ... Args>
std::string toBytes(Args... args)
{
std::ostringstream buf;
boost::archive::binary_oarchive arch(buf);
(arch << ... << args);
return buf.str();
}
这很好用,但是当我尝试将指针序列化为某种基本类型(比如char*
)时,它会扼杀它。据我所知,Boost.Serialization没有按意图将这些类型开箱即用。所以,我想提供一种“默认”方式来序列化它们。
为了达到这个目的,我希望通过一些函数args
映射每个f
元素,这样f(char*)
将返回CharPtrWrapper
,而其他类型的f
应该作为身份函数。
我的方法是:
template<typename T>
T f(T x) { return x; }
template<>
CharPtrWrapper f(char * x) { return CharPtrWrapper(x); }
但是这段代码给出了
错误C2912:显式特化'CharPtrWrapper f(char *)'不是函数模板的特化
这有什么问题,我该如何解决这个问题?
这有什么问题,我该如何解决这个问题?
问题是你的专业化不是专业化。
通用f<>()
定义为:
template<typename T>
T f(T x) { return x; }
即,接收类型T
并返回相同类型的模板函数。因此,f<>()
的特化必须返回它收到的相同类型。
然而,
template<>
CharPtrWrapper f(char * x);
不是f<>()
的有效专业化,因为它接收char *
并返回CharPtrWrapper
。
f<>()
的一些有效专业是:
template <>
char const * f<char const *>(char const * x) { return x; }
// or
template <>
char const * f(char const * x) { return x; }
正如n.m.所建议的那样,解决方案是避免专业化而是使用重载。这意味着,从实际的角度来看,删除“template<>
”部分并简单地写:
CharPtrWrapper f(char * x) { return CharPtrWrapper(x); }
或者更好的是,收到char const *
而不是char *
。