gpt4 book ai didi

c++ - 什么时候实例化模板类的特殊成员函数?

转载 作者:可可西里 更新时间:2023-11-01 17:52:18 25 4
gpt4 key购买 nike

什么时候实例化模板类的特殊成员函数(特别是复制/移动构造函数和复制/移动赋值运算符)?一旦类本身被实例化,还是仅在需要它们时才实例化?

这出现在以下情况:

template <class T, class U>
struct pair
{
T first;
U second;

pair() : first(), second() {}

pair(const pair&) = default;
};

struct S
{
S() {}
S(const S&) = delete;
S(S&&) = default;
};

int main()
{
pair<int, S> p;
}

Clang 拒绝编译此代码,并出现以下错误:

test.cpp:9:5: error: the parameter for this explicitly-defaulted copy constructor is const, but a member or base requires it to be
non-const
pair(const pair&) = default;
^
test.cpp:21:18: note: in instantiation of template class 'pair<int, S>' requested here
pair<int, S> p;
^

表明它会在类实例化后立即尝试实例化复制构造函数。

但是,GCC 可以很好地编译代码,表明它只会在实际需要时才尝试实例化复制构造函数。

哪个编译器的行为是正确的?

(赋值运算符也存在类似的差异。)

更新:这与此示例中 pair 的复制构造函数是 default 的事实有关,因为如果我将其定义更改为

pair(const pair& p) : first(p.first), second(p.second) {}

然后代码也通过 clang。

最佳答案

查看当前 C++11 标准的第 14.7.1 节。引用 n3242 版本的草案:

The implicit instantiation of a class template specialization causes the implicit instantiation of the declarations, but not of the definitions or default arguments, of the class member functions, member classes, static data members and member templates; and it causes the implicit instantiation of the definitions of member anonymous unions. Unless a member of a class template or a member template has been explicitly instantiated or explicitly specialized, the specialization of the member is implicitly instantiated when the specialization is referenced in a context that requires the member definition to exist; in particular, the initialization (and any associated side-effects) of a static data member does not occur unless the static data member is itself used in a way that requires the definition of the static data member to exist.

因此,这意味着,当您将类用作上述类型时,只有声明会用它实例化。所以复制构造函数的实际(默认)实现不应该被实例化,因为在上面的代码中不需要它。所以 GCC 正确地处理了这个问题,而 Clang 没有。

您的编辑还表明,Clang 过早地为默认复制构造函数生成实现,因为您直接实现的复制构造函数也有错误(您不能像您那样调用 S 的复制构造函数在你自己的实现中做)。由于默认实现和您的实现在所有方面(包括实例化时间)都应该相同,因此我认为这是一个 clang 错误。

关于c++ - 什么时候实例化模板类的特殊成员函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10370713/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com