为什么我不能用make_pair打领带?
Why can't I use make_pair to tie?
我正在尝试模仿C++11之前的tie
的行为。
pair<int, int> test() {
return make_pair(13, 42);
}
int main() {
int a = 1, b = 2;
pair<int&, int&>(a, b) = test();
cout << a << ' ' << b << endl;
}
但是,如果我使用make_pair
来代替pair
构造函数a
和b
,则这是有效的
为什么pair
构造函数可以工作而make_pair
不能工作?
实际上您可以使用std::make_pair
。但是您需要实现reference_wrapper
类来模仿引用。示例(不是很完善,但如预期那样工作(c++03方法:
#include <iostream>
#include <utility>
using namespace std;
template <class T>
struct reference_wrapper {
bool is_const;
T* v;
T const* cv;
reference_wrapper(T& t): v(&t), is_const(false) { }
reference_wrapper(T const& t): cv(&t), is_const(true) { }
reference_wrapper &operator=(reference_wrapper const &rw) {
if (rw.is_const) {
*v = *rw.cv;
} else {
*v = *rw.v;
}
}
};
template <class T>
reference_wrapper<T> ref(T &t) {
return reference_wrapper<T>(t);
}
pair<int, int> test() {
return make_pair(13, 42);
}
int main() {
int a = 1, b = 2;
//pair<int&, int&>(a, b) = test(); // works
make_pair(ref(a), ref(b)) = test(); // now it does work
std::cout << a << ' ' << b << std::endl;
}
在20.2.2[lib.pears]8中,标准规定pair
使用"显式类型",而make_pair
的"类型是推导出来的"。
这就是为什么标准定义了pair
:的构造函数
template <class T1, class T2>
pair(const T1& x, const T2& y)
如果你在C++03编译器上运行你的代码,你会得到这个错误:
非静态引用成员
int& std::pair<int&, int&>::first
,不能使用默认分配运算符
问题是pair
使用隐式声明的拷贝分配运算符,如果pair
:
具有引用类型的非静态数据成员
无论是由make_pair
还是pair
构造函数定义,模板参数都会将pair
的两个成员定义为int&
,因此不会定义隐式声明的复制赋值运算符所以这不能用C++03中的pair
来完成。
如果不希望使用return参数,您可以编写自己的tie
:实现
template <class T1, class T2>
struct tie{
T1& first;
T2& second;
tie(T1& x, T2& y) : first(x), second(y) {}
tie<T1, T2>& operator=(const pair<T1, T2>& rhs){
first = rhs.first;
second = rhs.second;
return *this;
}
};
这将允许分配pair
:
tie<int, int>(a, b) = test();
要获得不需要模板参数的C++11行为,您需要定义一个函数。如果tie
嵌套在namespace details
中,则函数可以定义为:
template <class T1, class T2>
details::tie<T1, T2> tie(T1& x, T2& y) {
return details::tie<T1, T2>(x, y);
}
这将允许分配pair
,就像在C++11:中一样
tie(a, b) = test();
实时示例
请注意,这仍然不能容忍使用int&
模板参数,因此details::tie<int&, int&>
和tie<int&, int&>
将像以前一样失败
make_pair
生成一对值,而不是引用。这意味着它将在您的示例中生成pair<int, int>
,并且您将把test()
的结果分配给一个临时变量。
您可以使用以下内容模拟tie
:
template<typename T, typename U>
std::pair<T&, U&> tie_pair(T& l, U& r)
{
return std::pair<T&, U&>(l, r);
}
http://ideone.com/muAcaG
cco这是C++03没有ref限定符的不幸副作用。在C++≥11中,您可以删除右值this
的operator=
(在非std类中(,并使这种情况成为编译器错误,而不是无声的意外行为。
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 为什么我的for循环不能正确获取argv
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 为什么我不能在 FOR LOOP 中使用 i/10,C++?
- 为什么我不能在不创建字符串变量的情况下使用函数的字符串输出
- 为什么模板类中的对象不能返回值
- 为什么我不能在一个类的不同行中声明和定义成员变量?
- 为什么我不能在 C++ 中的特定函数重载中调用同一函数的任何其他重载?
- ld:bind_at_load和-bitcode_bundle(Xcode设置ENABLE_bitcode=YES)不能
- 数组长度,为什么从命令行获取时不能使用它?
- Windows/Cygwin - 不能使用 pybind11 - 犯错误
- 为什么我不能使用 EGL 创建无头 OpenGl 上下文?
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 为什么我不能将一个对象push_back到属于另一个类的对象向量中?
- 为什么我不能将 rand() 与数组的大小一起使用?
- 为什么虚函数不能是静态的和全局的?
- 为什么我不能在 while 循环中创建线程?
- ostream_iterator运算符=在pair<int,int>上失败,但在包装器类上工作。我不能为成对<>重载运算符<<吗?
- 为什么我们不能声明向量< int、pair<int、int > >