c++ - 可变参数模板函数的部分特化

标签 c++ function templates variadic-templates partial-specialization

我有这个函数应该递归工作。

template <class C, typename ...Arguments>
void addStyleClassRecursive(C *c, Arguments... arg)
{        
    c->addStyleClass(arg...);
    for (unsigned int i=0; i<c->children().size(); ++i)
    {
        addStyleClassRecursive(c->children()[i], arg...);
    }       
}

现在碰巧在某个时候我遇到了一个没有 addStyleClass 成员函数的类 (Wt::WObject),所以编译器提示 - 正确地 -这个问题。 好的。所以我想专门编写代码,为 Wt::WObject 添加一个版本:

template <class C=Wt::WObject, typename ...Arguments>
void addStyleClassRecursive(Wt::WObject *c, Arguments... arg)
{
    for (unsigned int i=0; i<c->children().size(); ++i)
    {
        addStyleClassRecursive(c->children()[i], arg...);
    }
}

这本身并没有给出编译器错误,但它被完全忽略了(实际上编译器一直提示 WObject 没有所需的成员函数,指向通用函数中的同一行).

所以我试着用这种方式专门化它

template <typename ...Arguments>
void addStyleClassRecursive<Wt::WObject, Arguments...>(Wt::WObject *c, Arguments... arg)
{
    for (unsigned int i=0; i<c->children().size(); ++i)
    {
        addStyleClassRecursive(c->children()[i], arg...);
    }
}

现在编译器提示

non-type partial specialization 'addStyleClassRecursive<Wt::WObject, Arguments ...>' is not allowed
 void addStyleClassRecursive<Wt::WObject, Arguments...>(Wt::WObject *c, Arguments... arg);
                                                                                        ^

那么谁能指出如何达到要求的结果呢?

最佳答案

你可以这样做:

template <class C, typename ...Arguments>
auto addStyleClassRecursiveImpl(int, C *c, Arguments... arg)
-> decltype(c->addStyleClass(arg...), void()) {
    c->addStyleClass(arg...);
    // ... C has addStyleClass
}

template <class C, typename ...Arguments>
void addStyleClassRecursiveImpl(char, C *c, Arguments... arg) {
    // ... C has not addStyleClass
}

template <typename... T>
void addStyleClassRecursive(T ...&&t) {
    addStyleClassRecursiveImpl(0, std::forward<T>(t)...);
    // ...
}

想法是将请求标记分派(dispatch)到内部实现(在示例中称为addStyleClassRecursiveImpl)并使用sfinae和函数重载选择正确的版本。


当然,您不能部分特化函数模板。

关于c++ - 可变参数模板函数的部分特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40425527/

相关文章:

c++ - 即使引用计数不为零,动态加载的 DLL 也可以被 Windows 卸载,如何处理?

javascript - 遍历数组,一次一个进行测验

linux - 将完整的 bash 脚本行传递给另一个 bash 函数以执行

c++ - 链接错误与 C++ 模板类和在单独的头文件中定义的嵌套类

c++ - 复制构造函数调用另一个类的复制构造函数

静态 vs 函数静态 vs 成员函数静态的 C++ 内存布局

c++ - Natvis FourCC 可视化语法

c++ - 如何从另一个函数读取函数中的输入值?

javascript - 在 Javascript 中获取原始函数

c++ - 使用 sfinae 启用/禁用 typedef 是不可能的。解决方法?