【问题标题】:Ambiguous overload on argument-less variadic templates无参数可变参数模板上的模棱两可的重载
【发布时间】:2011-12-19 21:42:06
【问题描述】:

相关:


考虑这对可变参数模板:

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&lt;rest...&gt; 不会扩展为对非模板函数的调用。

想法#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-arg 案例和一个 >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)。


无论如何,我应该认为我不能以直截了当的方式做这样一件基本的事情吗?是否需要使用带有额外虚拟模板参数的解决方法来完成此任务?

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

【问题讨论】:

  • 你所有后续的想法也有两个类/重载/专业化..你想在这里获得什么?
  • 你的想法 #3.5 有我的投票。如果您没有自己写出来,这就是我会回答的内容。如果我没记错的话,关于#3 是否模棱两可存在一些争论。我不确定尘埃落定在哪里,或者它是否已经落定。正是因为尘埃,我更愿意回避歧义问题并选择#3.5。
  • 霍华德说的。 +1 为问题所付出的努力
  • @Kos:我可能误解了这个问题,this 是否达到目标?
  • @IseWisteria,这正是我一直在寻找的;请张贴作为答案,以便您获得信用。

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


【解决方案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 或类似的调度 (虽然这会使代码有点冗长)。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-09
      • 1970-01-01
      • 2021-07-26
      • 1970-01-01
      • 1970-01-01
      • 2015-03-08
      • 2019-12-12
      相关资源
      最近更新 更多