gpt4 book ai didi

c++ - 关于模板类特化的范例

转载 作者:搜寻专家 更新时间:2023-10-31 00:11:05 24 4
gpt4 key购买 nike

我目前正在编写一个模板类,用于将数据归档(或序列化)和取消归档为二进制格式的数据。首先,我试图结束我将使用的模式。我主要倾向于使用模板,因为 unarchiver 没有用于方法重载的输入类型。例如,下面的例子就可以了:

Archiver ar;
int i;

archive(ar, i);

但它的对应物不是:

Unarchiver unar;
int i;

i = unarchive(unar);

我想避免使用函数的名称,例如 unarchive_int因为用模板的时候会很麻烦。说:

template <class T> class SomeClass
{
public:

void doSomething()
{
// Somewhere
T value = unarchive(unar);
}
};

这会使事情变得困惑,因此我宁愿为此使用模板,而前面的表达式将是 T value = unarchive<T>(ar); .如果第一个或唯一的参数总是归档器和非归档器对象,那么编写一个全局函数似乎也很愚蠢(可以说);一个模板类似乎是有序的:

template <class T> class Archiver
{
public:

void archive(T obj);
};

这可行,但归档方法总是复制其输入对象。这对于 POD 数据类型是可以的,但对于哪些类则不然。解决方案似乎很明显,而是使用 void archive(const T & obj) 中的 const 引用,但现在通过引用传递整数、 float 和其他 POD 似乎也很愚蠢。虽然我对这个解决方案很满意,但我尝试更进一步,让对象做出区分。我的第一个方法是 std::enable_if ,同时默认假设一个拷贝(对于所有非类成员)并提供类特化,其中 archive方法通过引用获取其输入。它不起作用。这是代码:

template <class T, class E = void>
class Archiver
{
public:

// By default, obj is passed by copy
void archive(T obj);
};

template <class T>
class Archiver<T, typename std::enable_if<std::is_class<T>::value && !std::is_pod<T>::value>::value>
{
public:

// I would expect this to be used instead if is_class<T> && !is_pod<T>
void archive(const T & obj);
};

问题是第二个声明对编译器根本不可见,证据如下:

template <> void Archiver<std::uint8_t>::archive(uint8_t obj);
template <> void Archiver<std::string>::archive(const std::string & obj);

前者编译正常,但后者给出:

out-of-line declaration of 'archive' does not match any declaration in 'Archiver<std::__1::basic_string<char>, void>'

另一方面,如果我得到 std::string如果编译正常,则通过复制代替。我想我知道为什么会发生这种情况,编译器选择第一个模板,因为它对两个声明都足够通用,但是我如何让它选择更专业的版本?

最佳答案

你想要 std::enable_if<...>::type , 不是 std::enable_if<...>::value .

Here's a full demo :

#include <type_traits>
#include <cstdint>
#include <string>

template <class T, class E = void>
struct Archiver {
void archive(T obj);
};

template <class T>
struct Archiver<T, typename std::enable_if<std::is_class<T>::value && !std::is_pod<T>::value>::type>
{
void archive(const T & obj);
};

template <> void Archiver<std::uint8_t>::archive(std::uint8_t obj);
template <> void Archiver<std::string>::archive(const std::string & obj);

关于c++ - 关于模板类特化的范例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35104302/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com