【发布时间】:2022-01-03 22:18:26
【问题描述】:
此问题与Get return type of function in macro (C++) 类似,但已有 10 年历史,没有人回答。任何其他解决方案都将被接受。
我想创建一个仅在不满足条件时从函数返回的断言宏,例如:
#define ASSERT(X) if(!(X)) return {};
如果包含函数返回 void,这将不起作用,但我不想创建 2 个宏。我希望能够在不更改代码的情况下添加/删除返回值。我的想法是创建一个辅助函数:
template<class T>
T re(){
if constexpr( std::is_same<T, void>::value ){
return;
}
else if constexpr( ! std::is_same<T, void>::value ){
return {};
}
}
现在宏可以像这样工作:
double f(int *i){
if(i == nullptr){
typedef std::invoke_result<decltype(&f),int>::type T; // only works for this function
return re<T>();
}
return 1.0;
}
但我需要当前函数的返回类型 T 而不必调用 ASSERT(i != nullptr, double) 之类的东西,因为这样我就可以简单地使用 2 个宏。此外,像 __func__ 和 std::source_location 这样的宏只是字符串。
【问题讨论】:
-
return {}不起作用,但return void()起作用。 -
当我做这样的事情时,我最终编写了 3 个单独的宏,它们都称为一个通用宏。我曾经必须返回的唯一值是
-1、nullptr和false。编辑:实际上,我只是偷看了代码,并没有void案例 - 这样的函数应该如何指示错误? -
@o11c 例如,我有自己的分配器,我不在乎是否有人调用 free(nullptr),但是是的,这个问题更多地是关于 c++ 的限制,而不是我遇到的真正问题。
-
在
ASSERT宏中隐藏像return这样的操作可能会令人惊讶,并且会使代码不那么明显。如果有很多地方需要这个宏,我会考虑将其拆分成更小的部分Bob大叔推荐的函数 -
是否可以选择使用 throw 而不是 return?那么你也不会对返回值有任何问题。
标签: c++ c++20 template-meta-programming