c++ - std::conditional 如何工作

标签 c++ c++11 templates template-meta-programming template-specialization

我们有这个叫做std::conditional 的元编程小奇迹描述here .在同一引用文献中,它说可能的实现是

template<bool B, class T, class F>
struct conditional { typedef T type; };

template<class T, class F>
struct conditional<false, T, F> { typedef F type; };

所以如果在代码中我做类似的事情

typename std::conditional<true,int,double>::type a;

编译器将遵循第一个定义,如果我做类似的事情

typename std::conditional<false,int,double>::type b

编译器将采用第二个。为什么这样行得通?这里有什么编译规则?

最佳答案

简而言之,它与模板特化规则有关。这些类似于函数重载,但针对的是类型。

在这里编译器更喜欢更专业的类型而不是更通用的类型。

template<bool B, class T, class F>
struct conditional { typedef T type; };

template<class T, class F>
struct conditional<false, T, F> { typedef F type; };

所以如果一个模板实例化coditional<false, ...>被它发现的编译器看到:

  • 通用模板template<bool B, class T, class F> struct conditional
  • 其所有专长:template<class T, class F> struct conditional<false, T, F>

此时它会尝试匹配尽可能多的专用参数,并最终选择带有 false 的特化。 .

例如引入另一个版本:

template<class F>
struct conditional<false, int, F> { typedef int type; };

并实例化一个模板类型,如 conditional<false, int, double>会更喜欢特化

template<class F> struct conditional<false, int, F>

template<class T, class F> struct conditional<false, T, F>与具有 2 个专用参数的版本相比,它更通用。

此时的一些技巧:

甚至可以只声明最通用的情况(即模板的通用形式只是声明但没有定义)并且只对你真正想要的情况进行专门化。所有非特化案例都将导致编译错误,并要求用户针对特定类型特化案例。

关于c++ - std::conditional 如何工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44550976/

相关文章:

c++ - 在无法访问的语句中创建变量是否是明确定义的行为?

c++ - 从函数返回 istream 的正确方法

C++:不同类型模板函数(方法)的自定义返回值

c++ - 在另一个共享库中使用共享库

c++ - 将模板(没有规范)传递给 std::thread() 会出现错误:<未解析的重载函数类型>匹配错误

c++ - 具有不同模板参数的相同类不能访问彼此的私有(private)字段

c++ - 以编程方式退出 MFC 应用程序的正确方法是什么?

c++ - 不能 phoenix::bind qi::_val with boost 1.53(回归?)

c++ - 在函数中计算模数与直接使用 % 运算符给出不同的答案

c++ - 带有 CRITICAL_SECTION 的模板类编译但在使用时出现错误