为什么声明函数的顺序会改变 SFINAE 选择的重载?
Why does order of declaring function changes overload chosen by SFINAE?
这个问题与有关。
在此示例中,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) and Clang (first, second) 中,定义模板和用户文字的顺序发生了变化,SFINAE 选择了哪些重载。为什么?
这是沼泽标准两阶段查找问题的变体。对于依赖函数名称,
- 非限定查找仅考虑模板定义上下文
- 参数相关查找同时考虑模板定义上下文和模板实例化上下文。
对于第二种情况,模板定义上下文中的非限定查找没有找到任何内容,并且 const char *
没有 ADL。
这个问题与
在此示例中,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) and Clang (first, second) 中,定义模板和用户文字的顺序发生了变化,SFINAE 选择了哪些重载。为什么?
这是沼泽标准两阶段查找问题的变体。对于依赖函数名称,
- 非限定查找仅考虑模板定义上下文
- 参数相关查找同时考虑模板定义上下文和模板实例化上下文。
对于第二种情况,模板定义上下文中的非限定查找没有找到任何内容,并且 const char *
没有 ADL。