gpt4 book ai didi

c++ - 为什么可变参数模板构造函数比复制构造函数更匹配?

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

以下代码无法编译:

#include <iostream>
#include <utility>

struct Foo
{
Foo() { std::cout << "Foo()" << std::endl; }
Foo(int) { std::cout << "Foo(int)" << std::endl; }
};

template <typename T>
struct Bar
{
Foo foo;

Bar(const Bar&) { std::cout << "Bar(const Bar&)" << std::endl; }

template <typename... Args>
Bar(Args&&... args) : foo(std::forward<Args>(args)...)
{
std::cout << "Bar(Args&&... args)" << std::endl;
}
};

int main()
{
Bar<Foo> bar1{};
Bar<Foo> bar2{bar1};
}

编译器错误提示我编译器试图使用可变参数模板构造函数而不是复制构造函数:

prog.cpp: In instantiation of 'Bar<T>::Bar(Args&& ...) [with Args = {Bar<Foo>&}; T = Foo]':
prog.cpp:27:20: required from here
prog.cpp:18:55: error: no matching function for call to 'Foo::Foo(Bar<Foo>&)'
Bar(Args&&... args) : foo(std::forward<Args>(args)...)

为什么编译器会这样做以及如何修复它?

最佳答案

这个调用:

Bar<Foo> bar2{bar1};

在其重载集中有两个候选人:

Bar(const Bar&);
Bar(Bar&); // Args... = {Bar&}

确定一个转换序列是否优于另一个的方法之一是,来自 [over.ics.rank]:

Standard conversion sequence S1 is a better conversion sequence than standard conversion sequence S2 if

— [...]
— S1 and S2 are reference bindings (8.5.3), and the types to which the references refer are the same type except for top-level cv-qualifiers, and the type to which the reference initialized by S2 refers is more cv-qualified than the type to which the reference initialized by S1 refers. [ Example:

int f(const int &);
int f(int &);
int g(const int &);
int g(int);

int i;
int j = f(i); // calls f(int &)
int k = g(i); // ambiguous

—end example ]

转发引用可变参数构造函数是更好的匹配,因为它的引用绑定(bind) (Bar&) 比复制构造函数的引用绑定(bind) (const Bar&) 更少 cv 限定。

就解决方案而言,您可以随时从候选集中排除Args...是你应该用 SFINAE 调用复制或移动构造函数的东西:

template <typename... > struct typelist;

template <typename... Args,
typename = std::enable_if_t<
!std::is_same<typelist<Bar>,
typelist<std::decay_t<Args>...>>::value
>>
Bar(Args&&... args)

如果Args...Bar 之一, Bar& , Bar&& , const Bar& , 然后 typelist<decay_t<Args>...>将是 typelist<Bar> - 这是我们想要排除的情况。任何其他组 Args...将被允许​​就好了。

关于c++ - 为什么可变参数模板构造函数比复制构造函数更匹配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31464666/

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