【发布时间】:2016-03-28 14:48:37
【问题描述】:
模板类std::common_type 计算一个通用类型到一个可变类型列表。 It is defined using the return type of the ternary operator x:y?z recursively. 从该定义来看,计算 std::common_type<X,Y> 是否具有关联性对我来说并不明显,即。 e.是否
using namespace std;
static_assert( is_same<common_type< X, common_type<Y,Z>::type >::type,
common_type< common_type<X,Y>::type, Z >::type>::value, "" );
对于is_same<...> 表达式有效的所有类型X、Y 和Z,永远不会抛出编译时错误。
请注意,我不是在问是否
static_assert( is_same<common_type<X,Y>::type,
common_type<Y,X>::type>::value, "" );
永远不会开火。显然不会。以上是一个完全不同的问题。
另请注意,std::common_type 的规范在 C++14 中略有变化,并且可能会在 C++17 中再次更改。因此,对于标准的不同版本,答案可能会有所不同。
【问题讨论】:
-
您是否会接受
(X,(Y,Z))具有通用类型但(X,Y)和(X,Y),Z没有的情况?或者您是否希望它们都解析为一种类型,但不同的类型。因为我很难为后者构建一个案例,并且强烈怀疑这是不可能的;任何两个转换链都会导致歧义。 -
static_assertion肯定会编译失败,因为没有通用类型。我假设问题是询问所有
common_type类型都有效但is_same为假的情况。 -
@JonathanWakely 感谢您的提示。修正了问题。
-
显然你可以让它不关联。但这没关系,如果它不具有关联性,那是因为您的设计中存在逻辑不一致。这就像以一种不符合逻辑的方式定义
operator==。 -
我认为这更像是一种学术兴趣,但无论哪种方式,我都不同意“那没关系......你的设计存在逻辑上的不一致”,因为(在一般意义上)并不总是需要关联性,并且可能会出现替换失败。我至少可以想到一个与
operator==参数相切的反例:向下转换为浮点数可能等于另一个浮点数,但是向上转换为双精度的浮点数很容易使相等失败。 (使用这个 impl。保证文档,但是将两者都转换为 LCM(此处为浮点数)或两者都转换为 GCM(此处为双精度)以强制执行 assoc。是极端情况 spackle。)
标签: c++ templates c++11 types metaprogramming