小编Mik*_*sev的帖子

定义外部成员模板功能

考虑这个(最小化)示例:

template <typename Descriptor>
class hash_table
{
public:
  typedef int value_type;

  template <typename Argument, int Callback (value_type *, Argument)>
  void traverse (Argument);

  template <int Callback (value_type *)>
  void traverse_void ();
};
Run Code Online (Sandbox Code Playgroud)

我定义了一个类模板,它具有带非类型参数的模板成员函数.请注意,这Callback取决于value_typetypedef.现在我想定义函数本身:

template <typename Descriptor>
template <typename Argument, int Callback (typename hash_table <Descriptor>::value_type *, Argument)>
void hash_table <Descriptor>::traverse (Argument) {}

template <typename Descriptor>
template <int Callback (typename hash_table <Descriptor>::value_type *)>
void hash_table <Descriptor>::traverse_void () {}
Run Code Online (Sandbox Code Playgroud)

我从编译器中得到了不一致的错误.结果不依赖于选项,指定C++标准的版本(即C++ 98,C++ 11和C++ 14的版本),但取决于编译器.

GCC 6.0.0(最近的主干,以及其他几个版本)接受此代码.

Clang 3.7.0(最近的trunk)给出以下错误:

test.cc:18:31: error: out-of-line …
Run Code Online (Sandbox Code Playgroud)

c++ templates member-functions language-lawyer

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

使用模板元编程实现静态版本的std :: all_of?

前言.我试图对C++模板元编程有一些更深入的了解,似乎我被卡住了...我正在编写一个库,我们将用它来进行二进制数据[de]序列化.正在解压缩的数据的预期结构在某种程度上是已知的,并且使用这些知识(1)验证数据(2)跳过不相关的部分以及(3)将数据直接解压缩到编译时已知的结构中似乎是合理的. - 用于避免不必要的复制并使客户端代码看起来更清晰.

因此,例如,我想实现一个解包数组的函数(数组可以包含异构数据,如JSON).为简单起见,假设数组具有固定大小,并且没有嵌套.


实际问题我想写一个函数,它将包含一个包含序列化数据的输入缓冲区(或一个流 - 在我们的上下文中无关紧要)和一个std::tuple包含输出的左值(参数包是一个更糟糕的选择,因为我最终必须处理嵌套问题.因此,我首先需要检查一个元组中的所有类型是否适合解包器,并提供相关的错误消息,如果不是.

所以代码是这样的:

template<typename T>
struct is_integral_lvalue : std::integral_constant<bool,
                            std::is_lvalue_reference<T>::value &&
                            std::is_integral<T>::value &&
                            (sizeof(T) == 4 || sizeof(T) == 8)>
{
};

/* ... */
template<typename TInputBuffer, typename... TDest>
static TRet unpack_int_tuple(TInputBuffer src_buf, std::tuple<TDest...> &&dest) noexcept(is_noexcept)
{
    static_assert(typelist::all_are<is_integral_lvalue, TDest...>::value,
                  "All types in a tuple must be integral lvalue-references");
    /* do unpacking */
}
Run Code Online (Sandbox Code Playgroud)

这种情况is_integral_constant可能有些武断.这就是为什么all_are模板可以使用任何一元谓词的原因.问题是:我应该写什么typelist::all_are(也许,我应该在上面的代码中解决什么才能编写这样的代码all_are)?

一个工作的例子当然是理想的,但如果它们有用,我会很感激一般的想法/建议.

限制我的目标不仅仅是实现这个功能,而是要了解它是如何工作的(像"使用boost :: mpl"或"boost :: hana"这样的解决方案是不合适的).我们使用的不太相关的东西越多越好.最好是代码应该是C++ 11(我们还没准备好在生产中使用C++ 1y/GCC …

c++ fold template-meta-programming c++11

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

内存加载何时导致x86-64 linux上的总线错误?

我曾经以为,支持x86-64的未对齐的内存访问和无效的内存访问总是引起分段错误(除非,也许,SIMD指令像movdqamovaps).不过最近我用正常mov指令观察到了总线错误.这是一个复制者:

void test(void *a)
{
    asm("mov %0, %%rbp\n\t"
        "mov 0(%%rbp), %%rdx\n\t"
        : : "r"(a) : "rbp", "rdx");
}

int main()
{
    test((void *)0x706a2e3630332d69);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

(必须用帧指针省略编译,例如gcc -O test.c && ./a.out).

mov 0(%rbp), %rdx指令和地址0x706a2e3630332d69是从有缺陷的程序的coredump复制的.将其更改为0会导致段0x706a2e3630332d60错误,但只是对齐仍然是总线错误(我的猜测是它与地址空间在x86-64上的48位相关).

问题是:哪些地址导致总线错误(SIGBUS)?它是由体系结构决定还是由OS内核配置(即在页表,控制寄存器或类似的东西中)?

c linux x86 assembly

3
推荐指数
2
解决办法
1299
查看次数