【问题标题】:Can "T t = {};" and "T t{};" produce different results?可以“T t = {};”和“T t{};”产生不同的结果?
【发布时间】:2020-09-12 10:20:24
【问题描述】:

问题很简单。有没有可能构造出这样一个类型T,下面的两个变量声明会产生不同的结果?

T t1 = {};
T t2{};

我已经研究了一个多小时的 cppreference 和标准,我明白了以下内容:

但最后一个很棘手,因为“列表初始化的影响”是一个令人印象深刻的......列表。对于类、基本类型和聚合,这似乎归结为值初始化。但我不确定我没有错过任何东西。

也许你可以提供一个上下文,其中两个声明会产生不同的效果?

UPD:关于explicit 构造函数的优秀答案!下一级:是否有可能两个语句都编译,但对编译/运行时间有不同的影响?

【问题讨论】:

  • 回复:UPD。现在你只是很难! ???我发现了一种情况,即两者都 fail 编译(但出于不同的原因),但是在它们都编译但给出不同结果的情况下工作。诡计多端。
  • 我可以将您的第一个案例更改为:T t1 = std::initializer_list<int>{};。你会考虑,还是我在作弊?
  • T t1 = std::initializer_list<int>{}; 绝对是作弊,因为我对我提供的确切表格感兴趣。
  • “我发现了一个两个都无法编译的案例(但原因不同)”——这也很有趣!可以分享一下吗?
  • 这是一个很好的“联合国”,可以肯定!只要你在大括号内输入一个值,它就变得很容易实现。问题在于让编译器将{} 明确视为(空)初始化列表。

标签: c++ initialization language-lawyer


【解决方案1】:

如果您考虑一种情况,其中一个语句编译,但另一个语句编译为“不同的效果”,那么是的,这是一个上下文:

#include <iostream>

class T {
public:
    int data{ 0 };
    explicit T() {
        data = 0;
        std::cout << "Default constructor" << std::endl;
    }
};

int main()
{
    T t1 = {};
    T t2{};
    return 0;
}

声明/初始化t1 的行给出以下内容,clang-cl

错误:选择的构造函数在复制初始化中是显式的

MSVC 编译器也抱怨:

错误 C2512:“T”:没有合适的默认构造函数可用
消息:类“T”的构造函数被声明为“显式”

【讨论】:

  • 太好了,谢谢!如果我想要编译这两个语句怎么办? :)
【解决方案2】:

区别在于explicit。我已经设法使 msvc 有所不同,但它看起来像一个编译器错误:

#include <iostream>
#include <initializer_list>

struct T
{
    template<class... A>
    T(A...) {std::cout << "1\n";}
    explicit T() { std::cout << "2\n"; }

};


int main()
{
    T t1 = {}; // 1
    T t2{}; // 2
}

【讨论】:

  • 太好了,谢谢!如果我想要编译这两个语句怎么办? :)
  • 是的,看起来像一个编译器错误。
猜你喜欢
  • 2018-12-02
  • 2015-07-30
  • 2013-10-26
  • 2018-03-27
  • 1970-01-01
  • 2018-01-05
  • 2012-05-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多