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

Ambiguous overload on argument-less variadic templates

本文关键字:模糊 重载 参数      更新时间:2023-10-16

相关:

  • 使用可变参数访问无参数模板函数的模糊重载
  • 简单的可变模板函数可以';t瞬时化
  • 为什么这个变差函数是不明确的

考虑这对可变模板:

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);
}

rest...为空的All<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);
}

这是不可行的,因为All(c(是不明确的。因此,我需要一个0-arg情况和一个>0-arg的情况。。。或者单参数情况和>1参数情况如何?

想法#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(上。


无论如何,我是否应该认为我不能以直接的方式做这样一件初级的事情?是否需要使用带有额外伪模板参数的变通方法来完成此任务?

或者是否有一个简单、正确的变体来指定零参数情况,这将起作用?

在这个问题的情况下,由于模板参数是非类型的,如果我们准备一个带有默认模板参数的函数,如以下,可以保存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或类似的调度(这会使代码变得有点长(。

看起来您的问题与以下问题类似:递归变分模板函数的编译错误

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