C++ 在编写包装现有函数并检查错误的模板函数时,如何使用完美转发?
我想包装一些对现有C库的函数调用,它调用函数,检查是否设置了错误条件,然后返回函数的值(如果有)。(特别是,这适用于OpenGl,但也适用于遗留的C函数。)函数可能返回void这一事实使这一点变得复杂,需要单独处理;我想抛出异常,这阻止我在保护对象的析构函数超出范围时进行检查 以下代码基本上起作用:C++ 在编写包装现有函数并检查错误的模板函数时,如何使用完美转发?,c++,templates,error-handling,C++,Templates,Error Handling,我想包装一些对现有C库的函数调用,它调用函数,检查是否设置了错误条件,然后返回函数的值(如果有)。(特别是,这适用于OpenGl,但也适用于遗留的C函数。)函数可能返回void这一事实使这一点变得复杂,需要单独处理;我想抛出异常,这阻止我在保护对象的析构函数超出范围时进行检查 以下代码基本上起作用: void check_for_error() { // check and handle legacy error messages // if (errno != 0) // if (glGetE
void check_for_error() {
// check and handle legacy error messages
// if (errno != 0)
// if (glGetError() != GL_NO_ERROR)
// throw std::runtime_error{"suitable error message"};
}
template <class R, class... Args>
using RvalFunc = R(*)(Args...);
// specialisation for funcs which return a value
template <class R, class... Args>
R exec_and_check(RvalFunc<R, Args...> func, Args... args) {
R rval = func(std::forward<Args>(args)...);
check_for_error();
return rval;
}
template <class... Args>
using VoidFunc = void(*)(Args...);
// specialisation for funcs which return void - don't store rval
template <class... Args>
void exec_and_check(VoidFunc<Args...> func, Args... args) {
func(std::forward<Args>(args)...);
check_for_error();
}
…而不是
glBindBuffer(target,name);
check_for_error();
FILE *pf = fopen("filename.txt", "rb");
check_for_error();
…检查可能会漏掉,这会使代码混乱。我希望R exec_和_检查(RvalFunc,Args…Args)
包含转发的通用参考(即Args&&…Args
),但这种替换会导致编译错误-Clang给出注意:忽略候选模板:例如,推断参数“Args”(vs.)的冲突类型
如何修改此代码以接受通用引用?或者我遗漏了什么,还有更好的方法来检查遗留代码吗?问题是您有两个模板函数,就编译器而言,它们只在返回类型上有所不同。要解决此问题,可以按如下方式使用SFINAE:
// specialisation for funcs which return a value
template <class R, class... Args>
std::enable_if_t<!std::is_void<R>::value, R>
exec_and_check(RvalFunc<R, Args...> func, Args... args) {
R rval = func(std::forward<Args>(args)...);
check_for_error();
return rval;
}
//返回值的函数的专门化
模板
std::如果\u t::value,R>
执行和检查(RvalFunc func,Args…Args){
R rval=func(std::forward)恐怕这不是问题所在-RvalFunc和VoidFunc是函数参数,Clang能够解决它们。我遇到的问题是我无法编写exec_和_check(RvalFunc,Args&&…Args)
为了获得完美的转发,这意味着传递给这些模板的某些参数无法按预期工作。不过,谢谢。很有趣。如果没有建议的更改,gcc无法解决这些问题,我认为这就是问题所在。另请参阅(请注意两个模板中的参数&&
),这是您想要的吗?
// specialisation for funcs which return a value
template <class R, class... Args>
std::enable_if_t<!std::is_void<R>::value, R>
exec_and_check(RvalFunc<R, Args...> func, Args... args) {
R rval = func(std::forward<Args>(args)...);
check_for_error();
return rval;
}