看一下std::is_same
的实现,我们可以看到一些内部函数(从integral_constant
继承)。为了方便起见,让我复制g ++代码:
template<typename _Tp, _Tp __v>
struct integral_constant {
static constexpr _Tp value = __v;
typedef _Tp value_type;
typedef integral_constant<_Tp, __v> type;
constexpr operator value_type() const noexcept { return value; }
constexpr value_type operator()() const noexcept { return value; }
};
template<typename, typename>
struct is_same : public integral_constant<bool, false> { };
template<typename _Tp>
struct is_same<_Tp, _Tp> : public integral_constant<bool, true> { };
这为我们提供了几种使用方法的选择:
bool a1 = is_same<int, int>{}; // instantiate & then cast implicitly
bool a2 = is_same<int, int>(); // instantiate & then cast implicitly
bool a3 = is_same<int, int>::value; // use static member
bool a4 = is_same<int, int>{}(); // instantiate & then use operator()
bool a5 = is_same<int, int>{}.operator()(); // instantiate & then use operator()
我想知道这些额外功能的用例是什么,为什么会这样?
之类的简短实现 template<class, class> constexpr bool is_same = false;
template<class T> constexpr bool is_same<T,T> = true;
不够吗?然后我们可以只写bool a = is_same<int,int>
而不用{}
或()
或::value
。
任何想法都很感激。
答案 0 :(得分:3)
这个答案在很大程度上是历史性的。类型特征比变量模板要早十年,因此您建议的选择是过时的。出于可用性方面的考虑,其余部分被逐个添加。
std::integral_constant
早在2003年就通过N1424引入。所以这是非常古老的技术,C ++ 03技术。当时看起来像这样:
template <class T, T v> struct integral_constant { static const T value = v; typedef T value_type; typedef integral_constant<T,v> type; };
您没有看到任何其他成员函数,请注意,value
也只是static const
,而不是static constexpr
。毕竟还没有constexpr
。
很多年后,在C ++ 0x的开发过程中,出现了一个库问题(LWG1019),由于新增了constexpr
,该问题扩展到:
template <class T, T v> struct integral_constant { static constexpr T value = v; typedef T value_type; typedef integral_constant<T,v> type; constexpr operator value_type() { return value; } };
N2976已解决此问题。
使用转换函数的动机是它使您可以将integral_constant
类型的对象用作这些值。对于某些元编程样式,如果您有直接返回true_type
的函数,则可以直接使用它:
std::true_type foo();
if (foo()) { ... }
不必写if (foo().value)
或类似的东西。但是,对于非布尔常量,从对象中获取值的唯一方法是访问value
成员或进行显式强制转换(后者要求您知道类型):
constant.value
static_cast<???>(constant)
导致N3545,在2013年,添加了call运算符,使您可以编写constant()
来拉回值。最后添加的内容真的有用吗?我不知道。
值得注意的是,所有这些 predates 变量模板-其第一个修订版为N3615。您建议将is_same
用作变量bool模板的选项直到后来才成为选项。即使使用变量模板,使用不同的类型也很方便,因此即使有可能,我也不确定我们会走这条路线。回想起来很难说。