小编ddc*_*dcc的帖子

在编译时使用C++对成员函数进行别名

假设我有一些通用代码,我想重用多个类来实现相同的底层功能,但是具有不同成员函数名的接口.例如,如果底层类具有erase成员函数,则以下代码将起作用,例如std::setstd::unordered_set.

template <typename T>
static std::chrono::duration<double> set_insert_time(const typename T::value_type &v) {
    T set;
    std::chrono::time_point<std::chrono::high_resolution_clock> start, end;
    start = std::chrono::high_resolution_clock::now();
    set.erase(v);
    end = std::chrono::high_resolution_clock::now();
    return end - start;
}
Run Code Online (Sandbox Code Playgroud)

但是,现在我想让这个函数与例如tbb::concurrent_unordered_set,它提供一个名为的函数unsafe_erase.

我最初的方法是利用具有部分模板特化的类型特征,通过定义以下内容,然后调用set_ops<T>::erase(set, v).不幸的是,这不会编译,因为它 tbb::concurrent_unordered_set是一个模板化的类而不是类型.我还尝试使用键类型的第二个模板参数扩展类型特征,但这无法编译,因为T它不是模板std::mem_fn(&T<U>::erase).

template <typename T>
struct set_ops {
  constexpr static auto erase = std::mem_fn(&T::erase);
};

template <>
struct set_ops<tbb::concurrent_unordered_set> {
  constexpr static auto erase = std::mem_fn(&T::unsafe_erase);
};
Run Code Online (Sandbox Code Playgroud)

我还尝试用函数模板包装成员函数,如下所示.这似乎是编译,但由于未定义的引用,例如,无法链接decltype ((({parm#1}.erase)({parm#2})),((bool)())) erase<std::set<unsigned int, std::less<unsigned …

c++ templates metaprogramming

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

在Linux 3.x上挂钩sys_execve()

我试图sys_execve()通过修改系统调用表来将函数挂接到Linux 3.x内核上。问题是sys_execve()仅在执行不成功时才应返回错误代码。使用我正在使用的包装函数(见下文),当sys_execve()在有效的可执行文件上调用该函数时,它可以正常执行,并且一切正常。但是,当在不存在的文件或其他导致错误情况的文件上调用该文件时,调用程序将崩溃,并显示以下内容:

segfault at 3b ip 000000000000003b...
Run Code Online (Sandbox Code Playgroud)

使用strace来检查钩子的返回值sys_execve()显示-1还是ENOSYS正确的错误代码,这使我感到困惑,因为我已经检查了包装函数的汇编以及的Linux源代码sys_execve()。为什么我的包装程序没有正确传递错误代码的任何建议?

asmlinkage long new_execve(const char* name, const char const** argv, const char const** envp, struct pt_regs* regs) {
    return orig_func(name, argv, envp, regs);
}
Run Code Online (Sandbox Code Playgroud)

c operating-system exec linux-kernel

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