这个问题与这个answer有关.
在此示例中,SFINAE 使用变量模板 has_literal_x
特化而不是基本模板:
struct A { };
A operator"" _x(char const*) { return {}; }
template<typename T, typename S, typename = void>
constexpr bool has_literal_x = false;
template<typename T, typename S>
constexpr bool has_literal_x<T, S,
std::enable_if_t<
std::is_same<
decltype(operator""_x(std::declval<S>())), T
>::value
>
> = true;
int main()
{
std::cout << has_literal_x<A, char const*> << std::endl; // 1
}
这里它使用基本模板:
template<typename T, typename S, typename = void>
constexpr bool has_literal_x = false;
template<typename T, typename S>
constexpr bool has_literal_x<T, S,
std::enable_if_t<
std::is_same<
decltype(operator""_x(std::declval<S>())), T
>::value
>
> = true;
struct A { };
A operator"" _x(char const*) { return {}; }
int main()
{
std::cout << has_literal_x<A, char const*> << std::endl; // 0
}
在 GCC(first、second)和 Clang(first、second)上,SFINAE 选择重载的定义模板和用户文字更改的顺序。为什么?
最佳答案
这是沼泽标准两阶段查找问题的变体。对于依赖函数名,
- 非限定查找只考虑模板定义上下文
- 依赖于参数的查找同时考虑模板定义上下文和模板实例化上下文。
对于第二种情况,模板定义上下文中的非限定查找什么也找不到,并且 const char *
没有 ADL。
关于c++ - 为什么声明函数的顺序会改变 SFINAE 选择的重载?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39781244/