[英]Get return type of current function in C++
这个问题类似于Get return type of function in macro (C++)但它已有 10 年历史,没有得到回答。 任何其他解决方案都将被接受。
我想创建一个断言宏,如果不满足条件,它只从 function 返回,例如:
#define ASSERT(X) if(!(X)) return {};
如果包含 function 返回 void,这将不起作用,但我不想创建 2 个宏。 我希望能够在不更改代码的情况下添加/删除返回值。 我的想法是创建一个助手 function:
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;
}
但是我需要当前 function 的返回类型 T 而不必调用诸如ASSERT(i,= nullptr, double)
之类的东西,因为这样我就可以简单地使用 2 个宏。 此外,像 __func__ 和 std::source_location 这样的宏只是字符串。
语句return X;
X
对于返回 function 的void
和返回任意类型的 function 均有效。
可以创建一种特殊的用户定义模板类型,其中return X;
将适用于多种类型。 例如return std::nullopt;
对于返回任何optional<T>
的 function 始终有效。 您可以从 object (如nullopt
)创建具有类似隐式转换属性的类似类型,该类型具有允许“携带” void
类型的特化( std::optional<void>
是不允许的,尽管您可以使用无状态类型作为void
的等价物)。
当然,这现在需要调用者从您的类型中提取返回值(如果有的话)。 这也意味着它必须检查是否返回了值。
expected<T, E>
类型(其中有几种实现)表示您正在谈论的类型。 不同之处在于它们带有T
或E
( T
== void
的特殊情况),其中带有E
表示期望返回的消费者处理的错误值。
但所有这些都需要更改函数的实际返回值。 如果您对使用简单类型(如void
、 double
、 int
等)很执着,那么无论您正在做什么返回,您都必须使用不同的宏。
这可以使用__PRETTY_FUNCTION__
(GCC, Clang) / __FUNCSIG__
(MSVC) 来实现,这是一个非标准扩展,它为您提供当前 function 的名称,包括返回类型。
您可以在编译时分析字符串以查看它是否包含void
:
#include <string_view>
struct AnyType
{
template <typename T>
operator T()
{
return {};
}
};
template <bool IsVoid>
auto foo()
{
if constexpr (IsVoid)
return;
else
return AnyType{};
}
#ifndef _MSC_VER
#define FUNCNAME __PRETTY_FUNCTION__
#else
#define FUNCNAME __FUNCSIG__
#endif
#define ASSERT(x) if (!bool(x)) return foo<std::string_view(FUNCNAME).starts_with("void ")>()
void x()
{
ASSERT(0);
}
int y()
{
ASSERT(0);
}
这需要更多的测试,以确保您不能用尾随返回类型破坏它,并通过向 function 定义(属性、调用约定等)添加各种内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.