标签: c++03

为什么使用=来初始化C++中的原始类型?

在我工作的地方,人们通常认为对象最好使用C++样式构造(带括号)初始化,而原始类型应该用=运算符初始化:

std::string strFoo( "Foo" );
int nBar = 5;
Run Code Online (Sandbox Code Playgroud)

但是,似乎没有人能够用这种方式解释他们为什么喜欢这样的东西.我可以看到std::string = "Foo";效率低下,因为它会涉及额外的副本,但是=完全放弃运算符并在各处使用括号有什么不对?

这是一个共同的惯例吗?这背后的想法是什么?

c++ coding-style c++03

8
推荐指数
3
解决办法
2801
查看次数

C++ 03下的参考折叠

我需要从绑定成员函数创建一个谓词,所以我将它包装在一个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_negateconst typename Predicate::argument_type& x参数),
  • 提升,因为argument_type即使实际参数是或者,也不应该引用 …

visual-c++-2008 c++03

8
推荐指数
1
解决办法
358
查看次数

在C++ 03中返回类似`std :: auto_ptr`的集合的最佳方法是什么?

std::auto_ptr不允许存储在STL容器中,例如std::vector.但是,偶尔会出现需要返回多态对象集合的情况,因此我无法返回对象向量(由于切片问题).我可以使用std::tr1::shared_ptr并坚持使用vector,但是我必须付出高昂的代价来维护单独的引用计数,并且拥有实际内存(容器)的对象不再在逻辑上"拥有"对象,因为它们可以被复制出来它不考虑所有权.

C++ 0x以这种形式为这个问题提供了一个完美的解决方案std::vector<std::unique_ptr<t>>,但是我无法访问C++ 0x.

其他一些说明:

  • 我无法访问C++ 0x,但我确实有TR1可用.
  • 我想避免使用Boost(尽管如果没有其他选项可以使用)
  • 我知道boost::ptr_container容器(即boost::ptr_vector),但我想避免这种情况,因为它打破了调试器(内部存储在void *s中,这意味着很难在调试器中查看实际存储在容器内的对象)

c++ collections memory-management auto-ptr c++03

7
推荐指数
1
解决办法
171
查看次数

unique_ptr C++ 03仿真中的move函数

我试图理解如何实现unique_ptr的C++ 03仿真.unique_ptr非常像std :: auto_ptr但更安全.在auto_ptr隐式转移所有权(即静默)的情况下,它会吐出编译器错误.例如,一个简单的任务.功能move是模拟unique_ptr安全性的关键.

问题:

  1. 为什么有三个移动功能?
  2. 接受引用并将其转换为右值的第三个移动函数实现(简化)如下.

    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>作为参数.为什么不自动拾取?

c++ unique-ptr move-semantics c++03

7
推荐指数
1
解决办法
1232
查看次数

在这里调用哪个构造函数?

在这个代码片段中,实际调用了哪个构造函数?

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++ c++03

7
推荐指数
1
解决办法
203
查看次数

从std :: type_info检索数据类型的大小

在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,但不是类型的大小.

c++ std c++03

7
推荐指数
1
解决办法
1595
查看次数

模板元代码和私有成员

我想做这样的事情:

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实现DoThingOneDoThingTwo.这不是一个鸭子类型的东西,我只想做这个额外的部分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 …

c++ templates c++11 c++03

7
推荐指数
1
解决办法
235
查看次数

使用std :: ifstream,忽略字符和搜索之间有区别吗?

我能找到的所有文档都说std::basic_istream<>::ignore(n)"提取并丢弃字符",但这种提取意味着什么并不十分清楚.

对于std::ifstream特别,可以实现使其等同于简单地seekg在文件中-ing?如果是这样,主流实现会这样做吗?

否则,如果字符在被丢弃之前确实被"读取",那么ignoreseekg可用时似乎是一个糟糕的选择(例如,使用文件或字符串流).

c++ iostream c++03

7
推荐指数
1
解决办法
189
查看次数

为什么标准C++语法不能涵盖这种情况?

我主要是指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形式 …

c++ grammar language-lawyer c++11 c++03

7
推荐指数
1
解决办法
350
查看次数

将相同的共享指针的副本存储在不同的向量中是一种好的做法吗?

我有一个基类,BaseObject和两个派生类DerivedObject1DerivedObject2.他们有共同的行为和方法,但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,一个存储所有指针的DerivedObject1DerivedObject2,另一个向量只存储指针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++ shared-ptr c++03

7
推荐指数
1
解决办法
380
查看次数