繁体   English   中英

为什么以下模板函数的重载决策模糊不清?

[英]Why is the following template function overload resolution ambiguous?

基于我对C ++的部分排序算法的理解,似乎第一个严格地是第二个定义的子集。 因此,只要两者都可以选择,第一个应该是首选。 但我收到以下错误消息:

p_o.cpp:13:10: error: call to 'f' is ambiguous
  return f<R>(args...);
         ^~~~
p_o.cpp:17:12: note: in instantiation of function template specialization 'f<int, double, int>' requested here
  auto a = f<int>(0.3, 1);
           ^
p_o.cpp:7:3: note: candidate function [with T = int, Ts = <>]
T f(T a, Ts ...args) {
  ^
p_o.cpp:12:3: note: candidate function [with R = int, T = int, Ts = <>]
R f(T a, Ts ...args) {
  ^
1 error generated.

有人可以解释我哪里错了吗? 我是元编程的新手。

#include <tuple>

using namespace std;

template <typename T, typename ...Ts>
T f(T a, Ts ...args) {
  return a;
}

template <typename R, typename T, typename ...Ts>
R f(T a, Ts ...args) {
  return f<R>(args...);
}

int main() {
  auto a = f<int>(0.3, 1);
  static_assert(is_same<int, decltype(a)>::value);
}

您可以将违规案例归结为以下内容:

f<int>(1);

这可以解释为对以下内容的调用:

R f<R, T, Ts...>(T, Ts...) // with `R = int`, `T=int` and `Ts = <>`

或致电:

T f<T, Ts>(T, Ts...) // with `T = int` and `Ts = <>`

请注意,部分模板排序的更专业化推理适用于参数类型,因此,它们都是相同的,因此2次重载被认为对您的调用同样有效,这导致了歧义。

要解决这个问题,你需要取消两个重载中的一个。 您似乎想要提取匹配所请求类型的包的第一个成员...为此,您可以使用基于SFINAE的设计:

template< typename R, typename T, typename... Ts >
std::enable_if_t< std::is_same< R, T >::value, R > f( T a, Ts... )
{
    return a;
}

template< typename R, typename T, typename... Ts >
std::enable_if_t< ! std::is_same< R, T >::value, R > f( T, Ts... args )
{
    return f< R >( args... );
}

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM