我们有这个叫做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/