小编Pau*_*cas的帖子

使用SFINAE检查全局运算符<<?

我想有几个重载的全局to_string()函数,它们采用某种类型T并将其转换为字符串表示形式.对于一般情况,我希望能够写:

template<typename T,class OutputStringType> inline
typename enable_if<!std::is_pointer<T>::value
                && has_insertion_operator<T>::value,
                   void>::type
to_string( T const &t, OutputStringType *out ) {
  std::ostringstream o;
  o << t;
  *out = o.str();
}
Run Code Online (Sandbox Code Playgroud)

has_insertion_operator到目前为止,我的实施是:

struct sfinae_base {
  typedef char yes[1];
  typedef char no[2];
};

template<typename T>
struct has_insertion_operator : sfinae_base {
  template<typename U> static yes& test( U& );
  template<typename U> static no& test(...);

  static std::ostream &s;
  static T const &t;

  static bool const value = sizeof( test( s << t ) …
Run Code Online (Sandbox Code Playgroud)

c++ templates sfinae

11
推荐指数
1
解决办法
2900
查看次数

取消注册通过register_callback()注册的回调?

我正在使用register_callback()注册iostreams的回调函数,如 标准C++ IOStreams和Locales中所述.202.

但是,无论是它还是我找不到的任何文件都说明如何取消注册回拨.可能吗?如果我将我正在使用的iword/pword归零,那么取消注册甚至是必要的吗?

c++ iostream

11
推荐指数
1
解决办法
491
查看次数

没有匹配的函数调用<anonymous enum>

鉴于:

template<typename T>
void f( T ) {
}

enum {    // if changed to "enum E" it compiles
  e
};

int main() {
  f( e ); // line 10
}
Run Code Online (Sandbox Code Playgroud)

我明白了:

foo.cpp: In function ‘int main()’:
foo.cpp:10: error: no matching function for call to ‘f(<anonymous enum>)’
Run Code Online (Sandbox Code Playgroud)

然而,如果enum声明被赋予一个名称,它就会编译.为什么它不能用于匿名枚举?理想情况下,我希望它能够将枚举值e提升为int实例化f(int).

c++ enums templates

10
推荐指数
2
解决办法
2228
查看次数

为什么std :: hash <T>不专用于char*?

为什么没有C++标准规定,std::hash<T>是专门为char*,const char*,unsigned char*,const unsigned char*,等?即,它将散列C字符串的内容,直到找到终止空值.

将我自己的特化注入我自己std的代码的命名空间有什么危害吗?

c++ hash stl stdhash

10
推荐指数
2
解决办法
3917
查看次数

C++成员函数链接返回类型和派生类

鉴于这个人为的例子:

struct point_2d {
  point_2d& x( int n ) {
    x_ = n;
    return *this;
  }

  point_2d& y( int n ) {
    y_ = n;
    return *this;
  }

  int x_, y_;
};

struct point_3d : point_2d {
  point_3d& z( int n ) {
    z_ = n;
    return *this;
  }

  int z_;
};

int main() {
  point_3d p;
  p.x(0).y(0).z(0); // error: "point_2d" has no member named "z"
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我们的想法是使用"member-function chaining"来连续调用多个成员函数.(有很多例子;上面是我能想到的最短的一个问题.我的实际问题是类似的,如下所述.)

问题是,如果派生类添加了自己的链接成员函数,但是首先调用基类的成员函数,则会得到一个基类引用,当然不能用于调用派生类的成员函数.

有没有聪明的方法来解决这个问题,仍然保持成员函数链的能力?


实际问题

我的实际问题是我的基类是一个异常,我的派生类是从基本异常派生的类.对于那些类,我也想使用成员函数链接:

class base_exception : …
Run Code Online (Sandbox Code Playgroud)

c++ member-functions derived-class

9
推荐指数
2
解决办法
1473
查看次数

为NSIS的LangString指定非ASCII字符

我正在使用NSIS为我的应用程序生成Windows安装程序.我想要一个多语言的安装程序.我正在LangString用于指定字符串.

但是,文档似乎没有说明如何编码非ASCII字符.例如,要使用德语单词"benötigt"(其中"o"具有变音符号),我该如何编码?

nsis

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

在C++中更简单的"防止派生类"

假设有一个合理的理由阻止从某个阶级派生出来,Bjarne 在这里提出了一个解决方案:"我可以阻止人们从我的班级中衍生出来吗?"

但是,我想到了:

class final {
protected:
  final() { }         // line 3
};

class B : private virtual final {
};

class D : public B {  // line 9
};

int main() {
  B b;
  D d;                // line 14
}
Run Code Online (Sandbox Code Playgroud)

在尝试编译时,会得到:

foo.cpp: In constructor ‘D::D()’:
foo.cpp:3: error: ‘final::final()’ is protected
foo.cpp:9: error: within this context
foo.cpp: In function ‘int main()’:
foo.cpp:14: note: synthesized method ‘D::D()’ first required here 
Run Code Online (Sandbox Code Playgroud)

我的解决方案适用于所有情况吗?恕我直言,它更好,因为该类final是通用的,不需要预知类来防止派生.

c++ derived-class

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

抛出异常时抛出异常

这段代码:

#include <iostream>
#include <stdexcept>

using namespace std;

int throw_it() {
  throw range_error( "foo" );
}

int main() {
  try {
    throw throw_it();
  }
  catch ( exception const &e ) {
    cerr << e.what() << endl;
    return 0;
  }
}
Run Code Online (Sandbox Code Playgroud)

foo运行时打印,但保证这样做吗?更具体地说,在将异常结果抛出到已定义的行为的过程中抛出异常?是抛出最近抛出的异常的行为(如上面的测试代码那样)?

供参考:

$ g++ --version
i686-apple-darwin11-llvm-g++-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)
Run Code Online (Sandbox Code Playgroud)

c++ exception-handling

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

临时数据成员和API设计的终身扩展

假设我有一个跨平台Path类,如:

class Path {
public:
    // ...
    Path parent() const;                // e.g., /foo/bar -> /foo

    std::string const& as_utf8() const {
        return path;
    }
private:
    std::string path;
};
Run Code Online (Sandbox Code Playgroud)

所述parent()成员函数返回的父路径this的路径,所以它(正确)返回一个新构造的Path对象,它表示它.

对于将OS级别的路径表示为UTF-8字符串(例如,Unix)的平台,将as_utf8()引用直接返回到内部表示似乎是合理的,path因为它已经是 UTF-8.

如果我有以下代码:

std::string const &s = my_path.as_utf8();  // OK (as long as my_path exists)
// ...
Path const &parent = my_path.parent();     // OK (temporary lifetime extended)
Run Code Online (Sandbox Code Playgroud)

这两行都很好,因为:

  • 假设my_path持续存在,那么s仍然有效.
  • 返回的临时对象的生命周期parent()由const&.

到现在为止还挺好.但是,如果我有以下代码: …

c++ api-design temporary data-members

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

错误的私人基类无法访问?

使用g ++ 4.2.1编译此代码:

struct S { };
template<typename T> struct ST { };

template<typename BaseType>
class ref_count : private BaseType { };

template<typename RefCountType>
class rep_base : public RefCountType { };

class wrap_rep : public rep_base<ref_count<S> > {
  typedef rep_base<ref_count<S> > base_type;      // line 11
};
Run Code Online (Sandbox Code Playgroud)

我明白了:

bug.cpp:1: error: ‘struct S’ is inaccessible
bug.cpp:11: error: within this context
Run Code Online (Sandbox Code Playgroud)

但是,如果我更改wrap_rep要使用的类ST:

class wrap_rep : public rep_base<ref_count< ST<int> > > {
  typedef rep_base<ref_count< ST<int> > > base_type;
};
Run Code Online (Sandbox Code Playgroud)

它编译得很好.或者,如果我将原始代码更改为: …

c++ private base-class private-inheritance name-lookup

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