为什么添加另一个简单的构造函数会使简单的类不再是文字类型?

问题描述 投票:0回答:1

只需添加

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;
}();

这让我很困惑。 编译器对非默认构造函数怀恨在心?

c++ language-lawyer constexpr
1个回答
0
投票

谢谢,它有效。但为什么呢?

因为之前的问题是参数化 ctor 不是 constexpr,所以我们不能在 constexpr 上下文中使用它。正如您所注意到的,如果我们创建参数化 ctor

constexpr
,程序将开始工作。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.