小编mar*_*ack的帖子

下标运算符的标准C++函数对象模板

说我目前有这样的模板功能:

template <class T, class K>
void* get_subobject(K key)
{
  T& obj = function_returning_T_ref<T>();

  // do various other things...

  return &obj[key];
}
Run Code Online (Sandbox Code Playgroud)

我想使下标操作可配置,以便用户可以应用自己的代码来映​​射objkey返回值.像这样的东西:

template <class T, class K, class Op = subscript<T, K>>
void* get_subobject(K key)
{
  T& obj = function_returning_T_ref<T>();

  // do various other things...

  return &Op{}(obj, key);
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,对于subscript<T,K>上面的默认模板参数是否有一个标准模板(沿着std::less<T>我的行),我可以在这里使用Op默认调用operator[]?我看不到任何合适的东西<functional>.

如果没有这方面的标准模板,我最好自己创建或者是否有某种方式可以使用std::bind()或类似于相同的效果而无需额外的开销?

c++ c++11

6
推荐指数
1
解决办法
279
查看次数

C++ 11 thread_local变量可以从父线程继承其初始值吗?

我想要一个thread_local变量来更改应用程序的每个线程中应用的日志记录级别.像这样的东西:

enum class trace_level { none, error, warning, log, debug, verbose };
static thread_local trace_level min_level = trace_level::log;
Run Code Online (Sandbox Code Playgroud)

trace_level::log应用程序启动时,默认值应该是主线程,但如果在启动其他线程之前更改它,那么我希望子线程以父项的当前值开始.

有没有办法使用thread_local变量?由于此代码隐藏在库中,因此无法在每个线程的开头手动设置值.

c++ multithreading c++11

6
推荐指数
1
解决办法
1274
查看次数

C++ 11在constexpr函数中初始化具有统一值的数组

我有一个类模板,它基于模板参数构建一个简单的数组作为其成员之一.我需要能够将数组中的每个元素初始化为其中一个构造函数中的单个值.不幸的是这个构造函数必须是constexpr.

相关部分归结为:

template <typename T, size_t N>
class foo
{
  T data[N];

  constexpr foo(T val)
  {
    // initialize data with N copies of val
  }
};
Run Code Online (Sandbox Code Playgroud)

使用std::fill或循环与constexpr要求不兼容.初始化: data{val}仅设置数组的第一个元素,并对剩余部分进行零初始化.

怎么能实现这一目标?

我觉得应该有一个可变参数模板和元组等的解决方案......

c++ constexpr c++11

6
推荐指数
2
解决办法
1578
查看次数

使用aligned_storage时如何避免严格的别名错误

我正在使用std::aligned_storage变体模板作为后备存储.问题是,一旦我-O2在gcc上启用,我就会开始收到"取消引用类型 - 惩罚指针会打破严格别名"的警告.

真实模板要复杂得多(在运行时检查类型),但生成警告的最小示例是:

struct foo
{
  std::aligned_storage<1024> data;

  // ... set() uses placement new, stores type information etc ...

  template <class T>
  T& get()
  {
    return reinterpret_cast<T&>(data); // warning: breaks strict aliasing rules
  }
};
Run Code Online (Sandbox Code Playgroud)

我很确定boost::variant与此基本上是一样的,但我似乎无法找到他们如何避免这个问题.

我的问题是:

  • 如果aligned_storage以这种方式使用违反严格别名,我应该如何使用它?
  • 实际上是否存在严格别名问题,get()因为函数中没有其他基于指针的操作?
    • 如果get()被内联呢?
    • 怎么样get() = 4; get() = 3.2?由于intfloat不同的类型,该序列可以重新排序吗?

c++ strict-aliasing c++11

5
推荐指数
1
解决办法
685
查看次数

C++模板将函数转换为函数对象类型

我正在尝试使用std::unique_ptr自定义删除器来简化管理从各种 C API 返回给我的句柄的生命周期。这在理论上很好,但我正在努力寻找一种既在运行时最佳,又没有针对每种包装类型的样板文件堆的方法。

例如,考虑一些不透明类型foo,必须通过将其指针传递给来释放它destroy_foo

// approach 1: pass destroy_foo at runtime (bad for performance)
using foo_ptr = std::unique_ptr<foo, decltype(&destroy_foo)>;
foo_ptr bar{create_foo(...), destroy_foo};


// approach 2: make a deleter type (verbose - for many types)
struct foo_deleter
{
  void operator()(foo* p)
  {
    destroy_foo(p);
  }
};
using foo_ptr = std::unique_ptr<foo, foo_deleter>;
foo_ptr bar{create_foo(...)};
Run Code Online (Sandbox Code Playgroud)

第一种方法很难让编译器优化,因为我传递了一个函数指针,所以它被淘汰了。第二种方法似乎不必要地冗长。我有很多这样的类型想要管理,为每个类型手动创建一个类是很痛苦的。

如何定义一个类模板,它接受destroy_foo并给我一个相当于 的类型foo_deleter?或者有一个标准库模板可以做到这一点吗?

// best of both worlds - to_obj<Func> makes foo_deleter from destroy_foo...
using foo_ptr = std::unique_ptr<foo, …
Run Code Online (Sandbox Code Playgroud)

c++ templates template-meta-programming c++11

5
推荐指数
1
解决办法
2029
查看次数

如何忽略 CMakeLists.txt 中单个 CMake 命令的错误?

我有一个项目尝试CMakeLists.txt读取可能存在或不存在的文件。文件丢失不是问题,脚本可以处理这两种情况。如果我们可以检测到已知的 Linux 发行版,这将用于稍微调整编译环境:

file (READ /etc/redhat-release RHREL)
if (RHREL MATCHES "Red Hat Enterprise Linux Server release 6*")
   # tweak for RHEL6
elseif (RHREL MATCHES "Red Hat Enterprise Linux Server release 7*")
   # tweak for RHEL7
else()
   # either read failed, or we didn't match a known RHEL release
   # fallback to reasonable defaults
endif()
Run Code Online (Sandbox Code Playgroud)

问题是,当file(READ...)失败时,它似乎使用SEND_ERROR参数输出一条消息。这意味着我的配置按照我的预期继续进行包罗万象else(),但在配置结束时CMake拒绝生成Makefile.

我怎样才能file(READ)以这样的方式运行,以便我可以在本地处理错误并防止它们导致整个配置失败?

cmake

5
推荐指数
1
解决办法
9084
查看次数

获取没有实例的std :: bitset的大小

给定一个std::bitset大小的typedef ,我需要能够在编译时确定该大小.例如:

typedef std::bitset<37> permission_bits;
static_assert(permission_bits::size() == 37, "size must be 37");  // not valid
Run Code Online (Sandbox Code Playgroud)

以上是有点做作,但显示了一般问题.

据我所知,在标准中,没有静态的constexpr成员std::bitset可以让我提取大小.我错过了什么吗?如果没有,我可以做什么来在编译时提取大小?

c++ c++-standard-library c++11

4
推荐指数
2
解决办法
347
查看次数

使用可变参数模板参数构建枚举

我有一个相当简单的变体类,它支持一组预定义的类型,并提供一个枚举来指示哪些可用类型当前处于活动状态。像这样的东西:

class variant
{ 
  enum class type { integer, real, string, etc };
  type active_type() const;
  /* ... */ 
};
Run Code Online (Sandbox Code Playgroud)

我想将类变成一个模板,其中支持的类型作为模板参数提供:

template <typename... T>
class variant
{ 
  const std::type_info& active_type() const; // logical, but can't switch on it
  /* ... */ 
};
Run Code Online (Sandbox Code Playgroud)

我用来捕捉错误的一个关键特性是我可以switch在活动类型上,如果任何可能的情况被遗漏,编译器会发出警告。使用上述设计(也不使用boost::variant),这是不可能的。

我的问题是,有什么办法可以让我自动生成一个枚举,其枚举数与参数包中的参数数相同?

枚举的实际名称/值无关紧要,因为它们可以隐藏在用于将类型映射到正确枚举的 constexpr 函数后面。我可以想象这样的最终用法:

template <typename... T>
class variant
{
  enum class type { T... }; // magic here

  // specializations provided to map T into type (for use in case labels)
  template …
Run Code Online (Sandbox Code Playgroud)

c++ c++11

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