gpt4 book ai didi

c++ - 类层次结构中完美转发构造函数和复制构造函数之间的冲突

转载 作者:可可西里 更新时间:2023-11-01 18:37:57 24 4
gpt4 key购买 nike

我最近在尝试使用完美的转发构造函数实现类层次结构时遇到了一个问题。考虑以下示例:

struct TestBase {
template<typename T>
explicit TestBase(T&& t) : s(std::forward<T>(t)) {} // Compiler refers to this line in the error message

TestBase(const TestBase& other) : s(other.s) {}

std::string s;
};

struct Test : public TestBase {
template<typename T>
explicit Test(T&& t) : TestBase(std::forward<T>(t)) {}

Test(const Test& other) : TestBase(other) {}
};

当我尝试编译代码时出现以下错误:

Error 3 error C2664: 'std::basic_string<_Elem,_Traits,_Alloc>::basic_string(const std::basic_string<_Elem,_Traits,_Alloc> &)' : cannot convert parameter 1 from 'const Test' to 'const std::basic_string<_Elem,_Traits,_Alloc> &'

我的理解是,编译器将完美转发构造函数视为比复制构造函数更好的数学。参见示例 Scott Meyers: Copying Constructors in C++11 .在没有类层次结构的其他实现中,我可以通过 SFINAE 禁用完美转发构造函数作为复制构造函数。参见示例 Martinho Fernandes: Some pitfalls with forwarding constructors .当我尝试将提到的解决方案应用于此示例时,我仍然无法编译并出现相同的错误消息。

我认为一种可能的解决方案是避免完美转发,在构造函数中按值获取参数,而不是从它们移动到类变量。

所以我的问题是这个问题是否还有其他解决方案,或者在这种情况下是否无法完美转发?

更新:原来我的问题很容易被人误解。因此,我将尝试稍微澄清一下我的意图和背景。

  • 代码如问题中所贴的那样完整。没有创建其他对象或调用函数。尝试编译发布的示例时出现错误。
  • 拥有完美的转发构造函数的目的是为了成员初始化,不是拥有某种额外的复制构造函数。这里的原因是在使用临时对象初始化成员时保存一些对象拷贝(如 Scott Meyers 在演讲中提出的那样)
  • 不幸的是,事实证明完美转发构造函数可能会与其他重载构造函数发生冲突(在本例中为复制构造函数)。
  • 就像这个问题的答案和评论所建议的那样:这里可能的解决方案是引入显式强制转换或具有单独的非模板构造函数(即关于具有两个参数为 const string&string&&分别)。

最佳答案

尝试更改 Test(const Test& other) : TestBase(other) {}Test(const Test& other) : TestBase(static_cast<TestBase const&>(other)) {}

第二个Test constructor 正在调用 TestBase,有两种可能。其中一个接受任何东西,另一个接受 TestBase。但是您正在向它传递一个测试——“任何东西”都匹配得更好。通过显式转换为 TestBase const&,我们应该能够获得正确的匹配。

另一种可能性可能涉及 Test 的构造方式——也许您传入的内容与模板构造函数匹配,而不是 Test?我们可以通过从 Test 中删除模板构造函数并查看错误是否消失来测试这种其他可能性。

如果是这样,为什么您链接的技术(在推导的类型与测试匹配时禁用测试模板构造函数)不起作用?

关于c++ - 类层次结构中完美转发构造函数和复制构造函数之间的冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13160826/

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