我想了解这种行为的原因:
此代码非常完美:
#include <iostream>
#include <tuple>
struct SomeClass {
int v1;
int v2;
int v3;
};
auto pv1 = &SomeClass::v1;
auto pv2 = &SomeClass::v2;
auto pv3 = &SomeClass::v3;
auto t = std::tie(pv1, pv2, pv3);
int main() {
SomeClass c;
c.v1 = 111;
c.v2 = 222;
c.v3 = 333;
std::cout << c.*std::get<0>(t) << std::endl << c.*std::get<1>(t) << std::endl << c.*std::get<2>(t) << std::endl;
}
但这不会编译
#include <iostream>
#include <tuple>
struct SomeClass {
int v1;
int v2;
int v3;
};
auto t = std::tie(&SomeClass::v1, &SomeClass::v2, &SomeClass::v3);
int main() {
SomeClass c;
c.v1 = 111;
c.v2 = 222;
c.v3 = 333;
std::cout << c.*std::get<0>(t) << std::endl << c.*std::get<1>(t) << std::endl << c.*std::get<2>(t) << std::endl;
}
在gcc中出现以下错误
test.cpp:17:65: error: invalid initialization of non-const reference of type ‘int SomeClass::*&’ from an rvalue of type ‘int SomeClass::*’
auto t = std::tie(&SomeClass::v1, &SomeClass::v2, &SomeClass::v3);
^
In file included from test.cpp:2:0:
/usr/include/c++/4.8/tuple:1044:5: error: in passing argument 1 of ‘std::tuple<_Elements& ...> std::tie(_Elements& ...) [with _Elements = {int SomeClass::*, int SomeClass::*, int SomeClass::*}]’
tie(_Elements&... __args) noexcept
^
背景问题: 你可以怀疑,我想把元组中某些类的一些成员组合起来做一些模板魔术。
答案 0 :(得分:6)
如果我们查看std::tie的cppreference文档,它会说(强调我的):
template< class... Types > tuple<Types&...> tie( Types&... args );
为其参数或实例创建左值引用元组 of std :: ignore。
在您的第一种情况pv1
中,pv2
和pv3
都是左值,因此将非常量左值引用绑定到它们是有效的。
在第二种情况下,您传递rvalues,因此您无法将非const左值引用绑定到它们。您可以使用std::make_tuple:
来完成这项工作auto t = std::make_tuple(&SomeClass::v1, &SomeClass::v2, &SomeClass::v3);
我们可以看到将rvalue引用传递给make_tuple
确实有效:
template< class... Types > tuple<VTypes...> make_tuple( Types&&... args ); ^^