隐式默认构造的含义是什么?

14

这个参考页面上,对于std::tuple类型的默认构造函数指出,当且仅当对于至少一个索引值i,类型Ti不是隐式默认可构造的时候,该构造函数才是“显式”的。

我有点困惑“隐式默认可构造”是什么意思。能否给我一个例子?

2个回答

11

这里有一个例子:

struct A {};
struct B { explicit B() = default; };

int main()
{
    A a1 = {};
    A a2 {};

    // B b1 = {}; // Error, would use explicit default constructor
    B b2 {};
}

自C++11以来,具有 explicit 的构造函数因列表初始化而变得更加相关。


我明白了。我们能使用什么类型特征来测试一个类型是否可以隐式默认构造吗? - Zizheng Tai
@ZizhengTai,我不这么认为。由于在C++17中T t = {};不需要复制或移动构造函数,因此您可以创建一个。 - chris
@ZizhengTai,如果这个能够工作并且复制构造也能工作,那么你就可以检测到。但是如果复制构造不能工作,那么你就不会知道。我暂时想不出任何聪明的测试方法,但这并不意味着不能做到。 - chris
@ZizhengTai:标准提供了一个提示:“可以使用一个特性来检查是否可以使用{}初始化const T&。” - Kerrek SB
@KerrekSB 尝试这个只会导致各种编译器错误 :D - Zizheng Tai
显示剩余2条评论

8

这意味着,对于 std::tuple<T1,T2,...,Tn> 能够被隐式地默认构造,所有的 Ti 类型都必须具备该特性。

隐式默认可构造元组的示例

例如,由于 std::stringstd::vector 都是隐式默认可构造的(它们的默认构造函数不是 explicit),因此 std::tuple<std::string, std::vector> 也是隐式默认可构造的:

void f(std::tuple<std::string, std::vector<int>>);

f({}); // valid and equivalent to:
std::string sempty;
std::vector<int> vempty;
auto tsv = std::make_tuple(sempty, vempty);
f(tsv);

不隐式默认构造元组的示例

当类型A不具备隐式默认构造函数时,std::tuple<std::string, A>无法隐式默认构造:

struct A
{
    explicit A() = default;
};

void f(std::tuple<std::string, A>);

f({}); // error

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接