c++ - 从未使用过的无效默认成员初始值设定项

标签 c++ c++11 language-lawyer

请考虑以下代码:

template <typename T>
struct Test
{
    Test() = default;

    explicit Test(const T& arg)
     : m_member(arg)
    {
    }

    T     m_member{};
};

int main()
{
    Test<int>       t1;

    int             v2 = 34;
    Test<int&>      t2(v2);     // (!)

    return 0;
}

上面的代码是否应该编译并且没有未定义的行为?

标记 (!) 的行使用引用类型的参数实例化类模板 Test。在这种情况下,成员 Test::m_member 的默认初始化器是无效的(好吧,引用必须用某个对象初始化)。但另一方面,程序中从未使用过默认构造函数(唯一可以使用该默认初始化程序的构造函数),因此不应实例化它。

在 C++11 下,是否允许/要求编译器尝试/跳过实例化构造函数中使用的成员的默认初始化程序的实例化(即程序不实例化任何可能需要该初始化程序的构造函数)?

最佳答案

幸运的是,这还可以。

But on the other hand, the default constructor (the only one which could have used that default initializer) is never used in the program, and so it shouldn't be instantiated.

确实:

[temp.mem.func]/2

The template-arguments for a member function of a class template are determined by the template-arguments of the type of the object for which the member function is called.

因为在你的例子中,Test<int&>::Test()未被调用,它的模板参数未确定并且其构造不会使程序格式错误。

关于c++ - 从未使用过的无效默认成员初始值设定项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57775911/

相关文章:

c++ - 一个类可以在同一个命名空间中拥有另一个同名的成员吗?

c++ - 使用 fstream 将文件数据从当前位置保存到文件末尾

c++ - QWidget - 不确定从哪里开始

c++ - 覆盖析构函数是一种好习惯吗?

c++ - xcode 7 如何抑制警告 "overrides a member function but is not marked ' override'”

c++ - 文字运算符的模板参数列表

c++ - Curl 重定向问题 C++

c++ - 读取随机访问文件

c++ - 静态全局变量初始化顺序

c++ - 标准草案中提到的零长度数组是什么?