一个限制返回值的思路
问题
限制函数的返回值为 task<T>
task是一个模板类。
分析
如果仅是task
的,那不管是sfinae还是concepts都能轻松办到,但要限制的类型本身就是个范型那就得找另外的办法了,比如 source_location
,但这个需要C++20的支持,之前可以使用编译器自带的宏解决一下,下面使用source_location
实现个
实现
#include <string_view>
#if __has_include(<experimental/source_location>)
#include <experimental/source_location>
using sl = std::experimental::source_location;
#elif __has_include(<source_location>)
#include <source_location>
using sl = std::source_location;
#else
#error "not support"
#endif
template<typename T> struct task {};
template<typename F, typename... Args>
concept my_callable = requires(F&& f, Args&&... args)
{
{std::forward<F>(f)(std::forward<Args>(args)...)};
};
template<typename F, typename... Args> requires my_callable<F, Args...>
constexpr auto has_return_signature(std::string_view target, F&&, Args&&...)
{
std::string_view name{sl::current().function_name()};
auto beg = name.find("<")+1;
auto end = name.find(" (");
return name.substr(beg, end-beg) == target;
}
task<int> foo() { return {}; }
int bar() { return 0; }
void mo() {}
int main()
{
static_assert(has_return_signature("task<int>", foo));
static_assert(has_return_signature("int", bar));
static_assert(has_return_signature("void", mo));
static_assert(has_return_signature("task", foo));
}
编译一下:
x.cc: In function ‘int main()’:
x.cc:39:37: error: static assertion failed
39 | static_assert(has_return_signature("task", foo));
还行吧,告辞。