std::pair 构造函数重载采用元组如何判断元组内容是否是 r-val 引用?

问题描述 投票:0回答:1

对于措辞尴尬的问题表示歉意。我的不确定性基于可以大致简化为以下场景的情况。

我有一个

Foo
类,我想要一个
std::pair<int, Foo>
对象。
Foo
定义如下:

class Foo
{
public:
    Foo(int& a, int& b) { std::cout << "constructor with lvals called\n"; ... }
    Foo(int&& a, int&& b) { std::cout << "constructor with rvals called\n"; ... }
...
};

现在,如果我创建我的

std::pair
,如下所示:

std::pair<int, Foo> myPair{std::piecewise_construct,
                           std::forward_as_tuple(1),
                           std::forward_as_tuple(2, 3)};

std::forward_as_tuple

的函数签名

template< class... Types >
tuple<Types&&...> forward_as_tuple( Types&&... args ) 

因此,我对

std::pair
的构造函数的调用应该解析为如下所示:

std::pair<int, Foo> myPair{std::piecewise_construct,
                           tuple<int&&>(1),
                           tuple<int&&, int&&>(2, 3)};

这将(我想)调用 std::pair: 的以下构造函数

template< class... Args1, class... Args2 > constexpr pair( std::piecewise_construct_t, std::tuple<Args1...> first_args, std::tuple<Args2...> second_args );
看起来这个构造函数会将 

Args1

 推断为 
(int)
 并将 
Args2
 推断为 
(int, int)
,因此 
second_args
 将绑定到从传递给它的 
tuple<int, int>
 参数复制的 
tuple<int&&, int&&>
 对象。但是,当我运行这段代码时,我确实得到了
“构造函数与 r-vals 调用”打印到屏幕上,所以显然 
second_args
 的内容是 r-val 引用,我的理解存在差距。我想我可能在 
std::pair
 的构造函数中的模板推导过程中遗漏了一些东西,但我不确定它是什么。

任何帮助表示赞赏!

c++ variadic-templates rvalue-reference std-pair stdtuple
1个回答
0
投票
你说得对,在推导过程中,引用崩溃了。但是,折叠不会影响元组元素本身的类型。因此,即使 int&& 在推导过程中折叠为 int,元组中的实际类型保持不变。

如果你这样做,你将得到左值打印。

int a = 2, b = 3; std::pair<int, Foo> myPair{std::piecewise_construct, std::forward_as_tuple(1), std::forward_as_tuple(a, b)};
这个链接对于模板参数推导非常有用。 

https://en.cppreference.com/w/cpp/language/template_argument_deduction

© www.soinside.com 2019 - 2024. All rights reserved.