只需添加
MyPair(const A& first, const B& second)
函数即可使“MyPair”不再是文字类型。
为什么?
template <class A,class B> class MyPair {
public: A first; B second;
public: using type_first=A;
public: using type_second=B;
MyPair() = default;
///vvv remove this constructor make "MyPair" a literal type
MyPair(const A& first, const B& second)
: first(first),
second(second) {
}
};
int main(){
constexpr MyPair<int,int> ssss=[](){return MyPair<int,int>{5,3};}();
///: ^ fail to compile
}
如果满足以下条件,则类型是文字类型:
- (否)标量类型;或
- (否)引用类型;或
- (否)文字类型的数组;或
- (是?)具有以下所有属性的类类型(第 9 条):
- (是的)它有一个简单的析构函数,
- (是)非静态数据成员(如果有)的每个构造函数调用和大括号或等于初始化器中的完整表达式都是 常数表达式 (5.19),
- (是?)它是一种聚合类型(8.5.1)或至少有一个 constexpr 构造函数或构造函数模板,但不是副本或 移动构造函数,并且
- (是的)它的所有非静态数据成员和基类都是文字类型。
我喜欢
constexpr
,但对literal type
还缺乏了解。
额外的实验...
如果没有有问题的构造函数,这段代码(相同的结果)出人意料地有效。
它实际上做了同样的事情,这就是我想要和期望的。
constexpr MyPair<int,int> ssss2=[](){
MyPair<int,int> re=MyPair<int,int>{};re.first=5;return re;
}();
这让我很困惑。 编译器对非默认构造函数怀恨在心?
谢谢,它有效。但为什么呢?
因为之前的问题是参数化 ctor 不是 constexpr,所以我们不能在 constexpr 上下文中使用它。正如您所注意到的,如果我们创建参数化 ctor
constexpr
,程序将开始工作。