我今天跑了一个非常微妙的问题我希望得到你的意见.
考虑以下花园式共享体成语类:
struct S
{
S() : p_impl(new impl) {}
private:
struct impl;
boost::shared_ptr<impl> p_impl;
};
Run Code Online (Sandbox Code Playgroud)
当您尝试以下列方式将它们放入向量时,会出现这种乐趣:
std::vector<S> v(42);
Run Code Online (Sandbox Code Playgroud)
现在,至少使用MSVC 8,所有元素v共享同一个impl成员.实际上,导致这种情况的原因是vector构造函数:
template <typename T, typename A = ...>
class vector
{
vector(size_t n, const T& x = T(), const A& a = A());
...
};
Run Code Online (Sandbox Code Playgroud)
在这些场景中,只有一个S对象被默认构造,从中复制了它们的n元素vector.
现在,使用C++ 11,有rvalue引用.所以它不能像这样工作.如果a vector被构造为
std::vector<S> v(42);
Run Code Online (Sandbox Code Playgroud)
然后很可能,实现将选择默认构造n向量内的对象,因为复制构造可能不可用.在这种情况下,这将是一个突破性的变化.
我的问题是:
std::vector必须具有如上定义的构造函数,即.使用默认参数?特别是保证向量对象的条目被复制而不是默认构造?PS:请不要评论 …
我不喜欢using namespace std,但我也厌倦了键入std::在每一条战线cout,cin,cerr和endl.所以,我想给他们这样简短的新名字:
// STLWrapper.h
#include <iostream>
#include <string>
extern std::ostream& Cout;
extern std::ostream& Cerr;
extern std::istream& Cin;
extern std::string& Endl;
// STLWrapper.cpp
#include "STLWrapper.h"
std::ostream& Cout = std::cout;
std::ostream& Cerr = std::cerr;
std::istream& Cerr = std::cin;
std::string _EndlStr("\n");
std::string& Endl = _EndlStr;
Run Code Online (Sandbox Code Playgroud)
这有效.但是,上面有什么问题我错过了吗?有没有更好的方法来实现同样的目标?