C++ 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数?

C++ 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数?,c++,templates,copy-constructor,misra,C++,Templates,Copy Constructor,Misra,MISRA规则14-5-2规定: 当有一个模板构造函数具有一个作为泛型参数的单个参数时,应声明一个复制构造函数 我找不到任何东西可以用足够简单的术语向我解释为什么在这种情况下必须有一个复制构造函数 我看过 和 ,但两者都没有真正帮助我。我看到有人提到复制构造函数不存在,但是默认的构造函数不是仍然会被创建吗?我看到了对复制省略的引用,但我不明白为什么复制构造函数对它是必需的 据我所知,这可能属于良好的编程实践,以防。。。也可能是你刚刚进入了一个未定义的行为领域。 我应该寻找什么来确定违反此MISR

MISRA规则14-5-2规定:

当有一个模板构造函数具有一个作为泛型参数的单个参数时,应声明一个复制构造函数

我找不到任何东西可以用足够简单的术语向我解释为什么在这种情况下必须有一个复制构造函数

我看过 和 ,但两者都没有真正帮助我。我看到有人提到复制构造函数不存在,但是默认的构造函数不是仍然会被创建吗?我看到了对复制省略的引用,但我不明白为什么复制构造函数对它是必需的

据我所知,这可能属于良好的编程实践,以防。。。也可能是你刚刚进入了一个未定义的行为领域。
我应该寻找什么来确定违反此MISRA规则的代码是否在其当前代码库中造成风险?

除非您编写移动构造函数或移动赋值运算符,否则在C++11之前,复制构造函数始终可能被定义为已删除或未定义。如果您自己不声明,它将自动生成

现在,我对米斯拉的了解还不够,无法确定你提到的规则背后的原因,所以我想猜猜它是什么。如果您有一个带有单个泛型参数的模板构造函数,那么您可能不仅仅是在做一个简单的复制,而且您可能错误地认为所有的复制构造都将通过这个模板构造函数来完成。但是,如果您将该类的一个对象(使用模板构造函数的对象)与该类的另一个对象或从该类派生的对象进行复制构造,则将调用自动生成的复制构造函数,并且不会完成模板版本应该做的任何额外工作


简而言之,通过提供一个复制构造函数,即使同时提供一个带有单个泛型参数的模板构造函数,也可以确保复制构造始终按预期工作。此外,您可以显式地向类的潜在用户显示,除了模板构造函数之外,它还有一个正确的复制构造函数。

除非您编写移动构造函数或移动赋值运算符,否则在C++11之前,复制构造函数始终可能被定义为已删除或未定义。如果您自己不声明,它将自动生成

现在,我对米斯拉的了解还不够,无法确定你提到的规则背后的原因,所以我想猜猜它是什么。如果您有一个带有单个泛型参数的模板构造函数,那么您可能不仅仅是在做一个简单的复制,而且您可能错误地认为所有的复制构造都将通过这个模板构造函数来完成。但是,如果您将该类的一个对象(使用模板构造函数的对象)与该类的另一个对象或从该类派生的对象进行复制构造,则将调用自动生成的复制构造函数,并且不会完成模板版本应该做的任何额外工作


简而言之,通过提供一个复制构造函数,即使同时提供一个带有单个泛型参数的模板构造函数,也可以确保复制构造始终按预期工作。此外,您还明确地向类的潜在用户显示,除了模板构造函数之外,它还有一个合适的副本构造函数。

他们没有在这些规则后面用示例进行推理吗?我可以想象,这个特殊的规则旨在防止当有人认为通过传递类型const&他将调用这个模板构造函数时出现这种情况。C++对于复制构造函数似乎有一个丑陋的一面。例如,类可以删除了复制构造函数,但仍然正确地是\u copy\u constructibleI无法找到任何推理。我可能就是没有足够的资源。我使用的是一个静态分析工具,它引用了规则并显示失败,但没有解释隐含的风险。或者规则的推理。他们没有在这些规则背后加入任何带有示例的推理吗?我可以想象,这个特殊的规则旨在防止当有人认为通过传递类型const&他将调用这个模板构造函数时出现这种情况。C++对于复制构造函数似乎有一个丑陋的一面。例如,类可以删除了复制构造函数,但仍然正确地是\u copy\u constructibleI无法找到任何推理。我可能就是没有足够的资源。我使用的是一个静态分析工具,它引用规则并显示失败,但没有解释隐含的风险。也没有解释规则的原因。@DanielLangr在C++11之前,定义一个移动构造函数不会取消定义,因为前者根本不会编译。0_o@DanielLangr我把这两部分都改了。我还想说几秒钟前bipll刚刚说过的话:在C++11之前,拷贝构造函数总是被定义的。C++11代码不能是MISR
A-C++兼容。@Lundin我认为这是一个关键点。代码是用C++11编写的,MISRA2008标准正在针对它应用。那么,这种违反行为是否更像是对代码应用旧标准的产物,而不是一些实际的不安全编码实践?@Nelfeal我终于找到了MISRA标准,他们对他们的规则给出了解释。你的死定了。我冒昧地将你答案中与我产生完美共鸣的部分大胆地提了出来。你剩下的答案仍然是很好的内容,但我想强调这一点。显然欢迎您撤消我的更改。@DanielLangr在C++11之前,定义移动构造函数不会取消定义复制构造函数,因为前者根本不会编译。0_o@DanielLangr我把这两部分都改了。我还想说几秒钟前bipll刚刚说过的话:在C++11之前,拷贝构造函数总是被定义的。C++11代码不能与MISRA-C++兼容。@Lundin我认为这是一个关键点。代码是用C++11编写的,MISRA2008标准正在针对它应用。那么,这种违反行为是否更像是对代码应用旧标准的产物,而不是一些实际的不安全编码实践?@Nelfeal我终于找到了MISRA标准,他们对他们的规则给出了解释。你的死定了。我冒昧地将你答案中与我产生完美共鸣的部分大胆地提了出来。你剩下的答案仍然是很好的内容,但我想强调这一点。显然欢迎您撤消我的更改。