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

问题描述 投票:0回答:1

我正在使用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 *)'不是函数模板的特化

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

c++ templates variadic-templates c++17 template-specialization
1个回答
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 *

© www.soinside.com 2019 - 2024. All rights reserved.