模板功能用于映射特定类型并保持所有其他类型不变

时间:2017-12-18 10:56:27

标签: c++ templates variadic-templates c++17 template-specialization

我使用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没有按意图将这些类型开箱即用。所以,我想提供一个&#34;默认&#34;序列化它们的方法。

要实现这一目标,我希望通过某个函数args映射每个f元素,以便f(char*)返回CharPtrWrapper以及f应该返回的其他类型作为身份功能工作。

我的方法是:

template<typename T>
T f(T x) { return x; }

template<>
CharPtrWrapper f(char * x) { return CharPtrWrapper(x); }

但是这段代码给出了

  

错误C2912:显式特化&#39; CharPtrWrapper f(char *)&#39;不是功能模板的专业化

这有什么问题,我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

  

这有什么问题,如何解决这个问题?

问题是你的专业化不是专业化。

通用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 *