【问题标题】:Template function to map specific type and leave all other unchanged模板函数映射特定类型并保持所有其他不变
【发布时间】:2017-12-18 10:56:26
【问题描述】:

我正在使用 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 不会有意序列化此类类型。所以,我想提供一种“默认”的方式来序列化它们。

为了实现这一点,我想通过某个函数 f 映射每个 args 元素,以便 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 *)' 不是函数模板的特化

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

【问题讨论】:

  • 专业化必须在主模板之后。无论如何考虑改用重载。
  • CharPtrWrapper f(char * x) 不完全匹配 T f (T x) 是吗?

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


【解决方案1】:

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

问题是你的专精不是专精。

通用f&lt;&gt;() 定义为:

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

即接收类型T并返回相同类型的模板函数。因此,f&lt;&gt;() 的特化必须返回它接收到的相同类型。

然而,

template<>
CharPtrWrapper f(char * x);

不是f&lt;&gt;() 的有效特化,因为它接收char * 并返回CharPtrWrapper

f&lt;&gt;() 的一些有效特化是:

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

// or

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

n.m. 建议的解决方案是避免专门化并使用重载。这意味着,从实际的角度来看,删除“template&lt;&gt;”部分并简单地写:

CharPtrWrapper f(char * x) { return CharPtrWrapper(x); }

或者更好的是,接收char const * 而不是char *

【讨论】:

    猜你喜欢
    • 2019-09-07
    • 2019-12-14
    • 1970-01-01
    • 2017-04-04
    • 2019-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-17
    相关资源
    最近更新 更多