简体   繁体   English

对没有参数的可变参数模板函数的模糊调用?

[英]Ambiguous call to variadic template function with no parameters?

When running this: 运行时:

template <typename T>
struct CodeByType
{
    static const int32_t Value = 7;
};

template <>
struct CodeByType<int>
{
    static const int32_t Value = 1;
};

template <typename Arg, typename... Args>
int32_t Sum()
{
    // The compiler complains on this line
    return Sum<Arg>() + Sum<Args...>();
}

template <typename Arg>
int32_t Sum()
{
    return CodeByType<Arg>::Value;
}

int main()
{
    auto sum = Sum<int, char, double>();
}

I'm getting: 我越来越:

Error C2668 'Sum': ambiguous call to overloaded function 错误C2668'Sum':对重载函数的模糊调用

Can someone please explain why and how to overcome it? 有人可以解释为什么以及如何克服它?

This looks awfully similar to the below code, which does compile, so I suppose it has something to do with Sum not accepting any actual parameters. 这看起来非常类似于下面的代码,它编译,所以我想它与Sum不接受任何实际参数。

template <typename T>
T adder(T first) {
    return first;
}

template<typename T, typename... Args>
T adder(T first, Args... rest) {
    return first + adder(rest...);
}

int main()
{
    auto sum = adder(1, 7);
}

If you reduce your code to just: 如果您将代码简化为:

Sum<int>();

You get a more helpful error message: 您会收到更有用的错误消息:

 31 : <source>:31:16: error: call to 'Sum' is ambiguous auto sum = Sum<int>(); ^~~~~~~~ 17 : <source>:17:9: note: candidate function [with Arg = int, Args = <>] int32_t Sum() ^ 24 : <source>:24:9: note: candidate function [with Arg = int] int32_t Sum() ^ 1 error generated. 

So it is clearer that there is an overload ambiguity between the first overload with Args = <> and the second one. 因此更清楚的是,第一次重载与Args = <>和第二次重载之间存在过载模糊。 Both are viable. 两者都是可行的。

One would might think as specialization for a solution: 人们可能会认为解决方案的专业化:

template <typename Arg>
int32_t Sum<Arg>()
{
    return CodeByType<Arg>::Value;
}

which would indeed solve the issue, had it been allowed by the standard. 如果标准允许,这确实可以解决问题。 Partial function specializations are not allowed. 不允许使用部分功能。

C++17 solution: C ++ 17解决方案:

This is the most elegant solution: 这是最优雅的解决方案:

constexpr if to the rescue: constexpr如果要救援:

template <typename Arg, typename... Args>
int32_t Sum()
{
    if constexpr(sizeof...(Args) == 0)
      return CodeByType<Arg>::Value;
    else
      return Sum<Arg>() + Sum<Args...>();
}

C++14 solution C ++ 14解决方案

We use SFINAE to enable/disable the function we want. 我们使用SFINAE来启用/禁用我们想要的功能。 Please note the function definition order had to be reversed. 请注意,必须颠倒函数定义顺序。

template <typename Arg, typename... Args>
auto Sum() -> std::enable_if_t<(sizeof...(Args) == 0), int32_t>
{
      return CodeByType<Arg>::Value;
}


template <typename Arg, typename... Args>
auto Sum() -> std::enable_if_t<(sizeof...(Args) > 0), int32_t>
{
      return Sum<Arg>() + Sum<Args...>();

}

C++11 solution C ++ 11解决方案

just replace std::enable_if_t<> with typename std::enable_if<>::type 只需用typename std::enable_if<>::type替换std::enable_if_t<>

In c++17, it would simply be 在c ++ 17中,它只是

template <typename... Args>
int32_t Sum()
{
    return (CodeByType<Args>::Value + ...); // Fold expression
}

In C++11, you may do: 在C ++ 11中,您可以:

template <typename... Args>
int32_t Sum()
{
    int32_t res = 0;
    const int32_t dummy[] = {0, (res += CodeByType<Args>::Value)...};
    static_cast<void>(dummy); silent warning about unused variable
    return res;
}

My memories of the template mechanism are old but if I recall correctly, their information is erased at a certain point in the compilation process. 我对模板机制的记忆很老,但如果我没记错的话,他们的信息会在编译过程中的某个时刻被删除。

My guess is that in the second case, the functions get distinguished not by the difference in the template types, but by the difference in the arguments. 我的猜测是,在第二种情况下,函数不是通过模板类型的差异来区分,而是通过参数的差异来区分。

In your case, you have no arguments, so stripped of the template information the two overloaded versions are equal and it cannot distinguish between them when you call it. 在您的情况下,您没有参数,因此剥离了两个重载版本相同的模板信息,并且在调用它时无法区分它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 对可变参数模板函数的模棱两可的调用 - Ambiguous call to variadic template function 在可变参数模板函数中对重载函数的模糊调用 - Ambiguous call to overloaded function in variadic template function 对重载可变参数模板 function 的模糊调用 - Ambiguous call on overloaded variadic template function 使用可变参数类模板的模板参数调用可变参数函数模板? - Call variadic function template with template parameters of variadic class template? 递归调用可变参数模板函数重载时的不明确调用 - Ambiguous call when recursively calling variadic template function overload 可变参数模板“对重载函数的模糊调用”似乎是一个错误的错误 - variadic template 'ambiguous call to overloaded function' seems a false error 可变参数 function 模板中的模糊模板专业化 - ambiguous template specialization in variadic function template 可变参数模板调用函数 - variadic template to call a function 变量模板作为std :: function的参数 - Variadic template as parameters to std::function 具有可变参数包的函数的C ++部分模板参数推导在Clang和MSVC中产生不明确的调用 - C++ partial template argument deduction for function with variadic pack produces ambiguous call in Clang and MSVC
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM