std :: enable_if的模糊部分特化

cha*_*eng 6 c++ templates partial-specialization disambiguation

我在下面的条件下遇到了一个问题:

#include <iostream>
#include <type_traits>

#define TRACE void operator()() const { std::cerr << "@" << __LINE__ << std::endl; }

template <class T>
struct check : std::true_type {};

template <class F, class T, class Check=void>
struct convert {
  TRACE;// first case
};

template <class F, class T>
struct convert<F*, T, typename std::enable_if<(check<F>::value && check<T>::value), void>::type> {
  TRACE; // second case
};

template <class T>
struct convert<int*, T, typename std::enable_if<(check<T>::value), void>::type> {
  TRACE; // third case
};
Run Code Online (Sandbox Code Playgroud)

然后

convert<int*, int> c;
c();
Run Code Online (Sandbox Code Playgroud)

将在g ++ - 4.5,g ++ - 4.6,g ++ - 4.7和clang ++ - 3.1(所有选项-std = c ++ 0x)中报告模糊的类模板实例化

但如果我将第三种情况的支票替换为

typename std::enable_if<(check<int>::value && check<T>::value), void>:type
Run Code Online (Sandbox Code Playgroud)

然后clang ++ - 3.1工作正常.

它是编译器错误还是标准错误?

Sin*_*all 0

你有

template <class F, class T>
struct convert<F*, T, typename std::enable_if<(check<F>::value && check<T>::value), void>::type> {
  TRACE; // second case
};
Run Code Online (Sandbox Code Playgroud)

template <class T>
struct convert<int*, T, typename std::enable_if<(check<T>::value), void>::type> {
  TRACE; // third case
};
Run Code Online (Sandbox Code Playgroud)

当您使用 时convert<int*, int> c;,编译器无法选择他需要使用哪个结构,因为它们都适合。

check<F>::value请注意,您在第一个模板中使用。这意味着即使你通过了,例如,int *你也会得到check<int>::value,而不是check<int *>::value

  • 可以肯定的是,第二个应该更专业,因为一方面它需要更少的模板参数。 (2认同)