c++ - 为什么声明函数的顺序会改变 SFINAE 选择的重载?

标签 c++ templates c++14 sfinae

这个问题与这个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(firstsecond)和 Clang(firstsecond)上,SFINAE 选择重载的定义模板和用户文字更改的顺序。为什么?

最佳答案

这是沼泽标准两阶段查找问题的变体。对于依赖函数名,

  • 非限定查找只考虑模板定义上下文
  • 依赖于参数的查找同时考虑模板定义上下文和模板实例化上下文。

对于第二种情况,模板定义上下文中的非限定查找什么也找不到,并且 const char * 没有 ADL。

关于c++ - 为什么声明函数的顺序会改变 SFINAE 选择的重载?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39781244/

相关文章:

c++ - 将向上转换指针转换为调用派生虚拟的基础对象

c++ - LLvm 即时通讯 : How to dereference a runtime pointer from jited code?

grails - 在 Grails 模板命名空间中,如何使用另一个目录中的模板

c++ - 类型比较

c++ - GCC 5.3.1 C++ 在编译 Variadic 模板时停止

c++ - 如何实现编译时字符串转换函数?

c++ - 在 Opengl ES 2.0 VBO 中使用 Eigen::Vector3f

c++ - 类的重新定义

c++ - 使模板类型更具体(T => Certain<X>)以帮助内容辅助

c++ - 为什么互斥锁和条件变量可以轻松复制?