无参数可变参数模板的模糊重载

时间:2011-11-01 22:40:33

标签: c++ c++11 variadic-templates template-meta-programming

相关:


考虑这对可变参数模板:

template<typename Dummy>
bool All(Param& c) {
    return true;
}

template<typename Dummy, Func* f, Func* ...rest>
bool All(Param& c) {
    return f(c) && All<Dummy, rest...>(c);
}

这可以工作和编译。但是,如何在没有第一个模板参数的情况下编写它?

听起来微不足道?嗯,这就是我的想法。 :-)让我们考虑一些想法。

想法#1:

template<Func* f, Func* ...rest>
bool All(Param& c) {
    return f(c) && All<rest...>(c);
}
template<>
bool All(Param& c) {
    return true;
}

不会起作用......当我尝试这个时,我心里有专长,但第二个想法并不是它的工作方式。

在原始示例中,我创建了两个不同的重载模板,首先采用1个模板参数,第二个采用2个或更多。没有歧义,也没有专业化。 我做得对吗?

想法#2:

bool All(Param& c) {
    return true;
}

template<Func* f, Func* ...rest>
bool All(Param& c) {
    return f(c) && All<rest...>(c);
}

显然无效,All<rest...>rest...为空时,不会扩展为对非模板函数的调用。

想法#3:

让我们重新解决一下这个问题。

template<Func* f>
bool All(Param& c) {
    return f(c);
}

template<Func* f, Func* ...rest>
bool All(Param& c) {
    return f(c) && All<rest...>(c);
}

这是一个禁忌,因为所有(c)都是模棱两可的。因此,我需要一个0-arg案例和一个&gt; 0-arg案例......或者说1-arg案例和&gt; 1-arg案例呢?

想法#3.5:

template<Func* f>
bool All(Param& c) {
    return f(c);
}

template<Func* f, Func* f2, Func* ...rest>
bool All(Param& c) {
    return f(c) && All<f2, rest...>(c);
}

是的,有效,但包含copypasta(在这种情况下很简单,但可能更大!),因此我认为它并不比我开始时更好。只是另一种解决方法。

想法#4:

让我们尝试#1但是使用类而不是函数。

template<Func* f, Func* ...rest>
struct All {
    static bool func(Param& c) {
        return f(c) && All<rest...>(c);
    }
};
template<>
struct All {
    static bool func(Param& c) {
        return true;
    }
};

这看起来很有希望,因为我可以专门化课程。但是,嘿,这是什么?

  

抱歉,未实现:无法将'rest ...'扩展为固定长度的参数列表

这不是GCC 4.4的事吗?我在MinGW GCC 4.6.1(tdm-1)上。


无论如何,我是否应该认为我不能用直接的方式做这样的基本事情?是否需要使用带有附加虚拟模板参数的变通方法来完成此任务?

或者是否有一个简单,正确的变体来指定零参数情况,这会有效吗?

2 个答案:

答案 0 :(得分:3)

在这个问题的情况下,由于模板参数是非类型的, 如果我们准备一个带有默认模板参数的函数,比如 以下,Dummy参数可以保存:

template<typename = void>
bool All(Param& c) {
    return true;
}

template<Func* f, Func* ...rest>
bool All(Param& c) {
    return f(c) && All<rest...>(c);
}

但是,我不确定这是否总是适用。 对于更一般的情况,可能需要std::enable_if或类似的调度 (这会使代码有点冗长)。

答案 1 :(得分:1)

看起来您的问题与此类似: Compilation Error on Recursive Variadic Template Function

那里有两个应该有效的答案;一个是你的#3.5,第二个是你没有的。