gpt4 book ai didi

c++ - 具有模板模板参数的模板定义中的函数特化

转载 作者:行者123 更新时间:2023-11-30 03:29:16 26 4
gpt4 key购买 nike

按照@Jonas 在 previous question 中的建议,我正在定义一个模板化类来保存任意容器(字符串、树等)的任意容器( vector 、集合、 map 等)。到目前为止,我的定义是这样的:

template <template <typename...> class Container, typename Containee = std::string, typename... extras>
class Lemario
{
public:
typedef typename Container<Containee, extras...>::iterator iterator;
typedef typename Container<Containee, extras...>::const_iterator const_iterator;
// Use 'Containee' here (if needed) like sizeof(Containee)
// or have another member variable like: Containee& my_ref.
Container<Containee, extras ...> mTheContainer;
int loadContainees(const char *filename) {
Containee w, line;
// do some stuff here
}
void appendContainee(const Containee &__x);
};

现在,我可以在模板定义之外定义内联方法(如 loadContainees)。外面:

template <template <typename...> class Container, typename Containee, typename... extras>
Containee Lemario<Container, Containee, extras...>::transform_word(const Containee& word) const
{
Containee result;
return result;
}

到目前为止一切顺利。

但现在我想专门化一种方法,将 Contaniee 作为 vector 、 map 、树附加到容器,使用不同的方法。所以我尝试专门化 std::vector:

template <template <typename...> class Container, typename Containee, typename... extras>
void Lemario<std::vector, Word>::appendContainee(const Word & word)
{
mTheContainer.push_back(word);
}

但是我得到以下错误:

error: prototype for ‘void Lemario<std::vector, gong::Xtring>::appendContainee(const Word&)’ does not match any in class ‘Lemario<std::vector, gong::Xtring>’

除此之外,“我可以只特化 Container,std::vector,而让 Containee 不特化吗?”

template <template <typename...> class Container, typename Containee, typename... extras>
void Lemario<std::vector, Containee>::appendContainee(const Containee & word)
{
mTheContainer.push_back(word);
}

最佳答案

问题是您的 appendContainee 实现有语法错误。为 std::vectorWord 专门化函数的正确方法是这样写:

template <>
void Lemario<std::vector, Word>::appendContainee(const Word & word)
{
mTheContainer.push_back(word);
}

Demo


但是,这种方法要求您每次都完全特化函数,这意味着您必须同时指定容器类型。可能您只想专攻 std::vector 而不是 Word

这个问题通常用tagged-dispatch 模式解决。在标记调度中,我们通过引入将通过重载正确选择的辅助方法,将特化转化为重载问题。

我们在我们的类中创建一个空的嵌套模板结构:

private:
template<class...>
struct Lemario_tag{};

然后编写入口点方法将调用的private 辅助方法:

template<class T>
void appendContaineeHelp(const Containee &x, Lemario_tag<T>)
{
static_assert(sizeof(T) == 0, "No specialization exists for this container");
}

void appendContaineeHelp(const Containee &x, Lemario_tag<std::vector<Containee, extras...>>)
{
mTheContainer.push_back(x);
}

第一个是包罗万象,如果您尝试使用非专用容器调用它,将导致编译器错误。

第二个专用于 std::vector

我们像这样定义我们的public appendContainee(简单传递):

void appendContainee(const Containee &x){
appendContaineeHelp(x, Lemario_tag<Container<Containee, extras...>>{});
}

我们可以像这样使用我们的容器:

Lemario<std::vector, std::string> vecString;
Lemario<std::vector, int> vecInt;
vecString.appendContainee("foo");
vecInt.appendContainee(1);

Lemario<std::set, int> set_int;
// set_int.appendContainee(1); // compiler error

Better Demo

关于c++ - 具有模板模板参数的模板定义中的函数特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45815694/

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