对于措辞尴尬的问题表示歉意。我的不确定性基于可以大致简化为以下场景的情况。
我有一个
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)};
的函数签名是
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
的构造函数中的模板推导过程中遗漏了一些东西,但我不确定它是什么。任何帮助表示赞赏!
如果你这样做,你将得到左值打印。
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