在我工作的地方,人们通常认为对象最好使用C++样式构造(带括号)初始化,而原始类型应该用=运算符初始化:
std::string strFoo( "Foo" );
int nBar = 5;
Run Code Online (Sandbox Code Playgroud)
但是,似乎没有人能够用这种方式解释他们为什么喜欢这样的东西.我可以看到std::string = "Foo";效率低下,因为它会涉及额外的副本,但是=完全放弃运算符并在各处使用括号有什么不对?
这是一个共同的惯例吗?这背后的想法是什么?
我需要从绑定成员函数创建一个谓词,所以我将它包装在一个boost::function<bool(SomeObject const &)>.这看起来很好,但是我还需要在一个案例中否定它.然而
boost::function<bool(SomeObject const &)> pred;
std::not1(pred);
Run Code Online (Sandbox Code Playgroud)
不能在MSVC++ 9.0(Visual Studio 2008)下编译,抱怨对引用的引用无效:
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\functional(213) : warning C4181: qualifier applied to reference type; ignored
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\functional(213) : error C2529: '_Left' : reference to reference is illegal
Run Code Online (Sandbox Code Playgroud)
问题是boost::function定义argument_typeas SomeObject const &和std::unary_negate<_Fn1>实例化由std::not1内部尝试使用const typename _Fn1::argument_type&和编译器拒绝它因为T::argument_type已经是一个引用.我确信这应该在C++ 11下编译,但这只是旧的编译器,只是C++ 03.所以我想知道它是谁的错:
unary_negate了const typename Predicate::argument_type& x参数),argument_type即使实际参数是或者,也不应该引用 …std::auto_ptr不允许存储在STL容器中,例如std::vector.但是,偶尔会出现需要返回多态对象集合的情况,因此我无法返回对象向量(由于切片问题).我可以使用std::tr1::shared_ptr并坚持使用vector,但是我必须付出高昂的代价来维护单独的引用计数,并且拥有实际内存(容器)的对象不再在逻辑上"拥有"对象,因为它们可以被复制出来它不考虑所有权.
C++ 0x以这种形式为这个问题提供了一个完美的解决方案std::vector<std::unique_ptr<t>>,但是我无法访问C++ 0x.
其他一些说明:
boost::ptr_container容器(即boost::ptr_vector),但我想避免这种情况,因为它打破了调试器(内部存储在void *s中,这意味着很难在调试器中查看实际存储在容器内的对象)我试图理解如何实现unique_ptr的C++ 03仿真.unique_ptr非常像std :: auto_ptr但更安全.在auto_ptr隐式转移所有权(即静默)的情况下,它会吐出编译器错误.例如,一个简单的任务.功能move是模拟unique_ptr安全性的关键.
问题:
接受引用并将其转换为右值的第三个移动函数实现(简化)如下.
T move(T &t) {
return T(detail_unique_ptr::rv<T>(t));
}
Run Code Online (Sandbox Code Playgroud)在上面的代码中,显式转换为T似乎是不必要的.实际上,Visual Studio 2010非常高兴,没有明确转换为T.
T move(T &t) {
return detail_unique_ptr::rv<T>(t);
}
Run Code Online (Sandbox Code Playgroud)
然而,g ++,clang,Comeau不喜欢第二个版本.这些编译器抱怨说,有没有构造函数unique_ptr<T>这需要detail_unique_ptr::rv<T>作为一个参数.这是为什么?unique_ptr已经定义了一个(非显式)构造函数,它detail_unique_ptr::rv<T>作为参数.为什么不自动拾取?
在这个代码片段中,实际调用了哪个构造函数?
Vector v = getVector();
Run Code Online (Sandbox Code Playgroud)
Vector有复制构造函数,默认构造函数和赋值运算符:
class Vector {
public:
...
Vector();
Vector(const Vector& other);
Vector& operator=(const Vector& other);
};
Run Code Online (Sandbox Code Playgroud)
getVector按值返回.
Vector getVector();
Run Code Online (Sandbox Code Playgroud)
代码使用C++ 03标准.
代码片段看起来应该调用默认构造函数然后调用赋值运算符,但我怀疑这个声明是使用复制构造函数的另一种形式.哪个是对的?
在C++ 03中,当您使用运算符typeid时,将返回type_info对象.
是否可以仅根据此结果检索给定类型的大小,例如sizeof运算符返回的大小?
例如:
std::type_info info = typeid(int);
int intSize = sizeof(int);
int intSize2 = info.getSize(); // doesn't exist!
Run Code Online (Sandbox Code Playgroud)
问题是我们使用第三方多数组类来返回type_info,但不是类型的大小.
我想做这样的事情:
template <typename T>
class Foo
{
...
public:
void DoSomething()
{
compile_time_if (T is ClassA)
{
m_T.DoThingOne();
m_T.DoThingTwo();
}
DoSomeFooPrivateThing();
m_T.DoThingThree();
}
T m_T;
};
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我知道所有有效的T工具DoThingThree,但只有ClassA实现DoThingOne和DoThingTwo.这不是一个鸭子类型的东西,我只想做这个额外的部分ClassA,我不想将这些方法添加到其他可能的Ts.我不能做转换,因为可能的Ts不是继承类型.
我知道我可以使用外部帮助器模板来满足这个要求:
template <typename T>
void Foo_DoSomething(T& t)
{
t.DoThingThree();
}
template <>
void Foo_DoSomething(ClassA& t)
{
t.DoThingOne();
t.DoThingTwo();
t.DoThingThree();
}
template <typename T>
class Foo
{
...
public:
void DoSomething()
{
Foo_DoSomething(m_T);
}
...
};
Run Code Online (Sandbox Code Playgroud)
但是现在这个外部模板无权访问Foo …
我能找到的所有文档都说std::basic_istream<>::ignore(n)"提取并丢弃字符",但这种提取意味着什么并不十分清楚.
对于std::ifstream特别,可以实现使其等同于简单地seekg在文件中-ing?如果是这样,主流实现会这样做吗?
否则,如果字符在被丢弃之前确实被"读取",那么ignore在seekg可用时似乎是一个糟糕的选择(例如,使用文件或字符串流).
我主要是指C++ 03标准,但是,在快速浏览之后,它也应该适用于C++ 11标准.
以下代码在VC++ 2010中成功编译和执行:
template<typename T>
class CC {
public:
T f(T a) {
return a*a;
}
};
template<>
class ::CC<int> { //<--- ::CC<int> syntax allowed by VC++2010, but is it non-standard ?
public:
int f(int a) {
return a*a;
}
};
int main(int argc, _TCHAR* argv[])
{
::CC<int> c;
}
Run Code Online (Sandbox Code Playgroud)
请注意::CC<int>语法以引用全局命名空间中定义的模板.这NamespaceA::CC<int>与::运算符前面的语法不同.使用其他一些工具,我试图使用C++ 03中的语法严格解析它,但它给了我错误,在我看来标准只接受NamespaceA::CC<int>类头声明中的表单.
仔细看看,问题在于class-head标准中的语法定义:
class-head:
class-key identifier(optional) base-clause(optional)
class-key nested-name-specifier identifier base-clause(optional)
class-key nested-name-specifier(optional) template-id base-clause(optional)
Run Code Online (Sandbox Code Playgroud)
而且由于nested-name-specifier形式 …
我有一个基类,BaseObject和两个派生类DerivedObject1和DerivedObject2.他们有共同的行为和方法,但DerivedObject1还有一个额外的方法.我的主类MyClass存储(in std::vector)boost::shared_ptr这些类的实例.MyClass需要调用commonMethod()所有BaseObject,有时需要调用additionalMethod()所有DerivedObject1.
class BaseObject
{
virtual void commonMethod();
}
Class DerivedObject1 : public BaseObject
{
void commonMethod();
void additionalMethod();
}
Class DerivedObject2 : public BaseObject
{
void commonMethod();
}
Run Code Online (Sandbox Code Playgroud)
有两个向量的缺点MyClass,一个存储所有指针的DerivedObject1和DerivedObject2,另一个向量只存储指针DerivedObject1?意思是我会有DerivedObject1两次所有的指针.但我认为对不同方法的要求至少是明确的.
class MyClass
{
typedef std::vector<std::shared_ptr<BaseObject>> BaseObjectVector;
typedef std::vector<std::shared_ptr<DerivedObject1>> DerivedObject1Vector;
BaseObjectVector everything;
DerivedObject1Vector only_derived1;
void doSomething()
{
for (BaseObjectVector::iterator iter = everything.begin(); …Run Code Online (Sandbox Code Playgroud) c++03 ×10
c++ ×9
c++11 ×2
auto-ptr ×1
coding-style ×1
collections ×1
grammar ×1
iostream ×1
shared-ptr ×1
std ×1
templates ×1
unique-ptr ×1