#include <iostream>
#include <boost/preprocessor.hpp>
#include <boost/callable_traits/is_invocable.hpp>
#define IS_VALID_EXPANDER_BEGIN(count) \
[](BOOST_PP_REPEAT(count, IS_VALID_EXPANDER_MIDDLE, \
_)) constexpr->decltype IS_VALID_EXPANDER_END
#define IS_VALID_EXPANDER_MIDDLE(z, idx, _) BOOST_PP_COMMA_IF(idx) auto _##idx
#define IS_VALID_EXPANDER_END(...) \
(__VA_ARGS__){})
#define IS_VALID(...) \
is_valid<__VA_ARGS__>(IS_VALID_EXPANDER_BEGIN( \
BOOST_PP_VARIADIC_SIZE(__VA_ARGS__))
template <typename... Ts, typename TF>
static constexpr auto is_valid(TF)
{
return boost::callable_traits::is_invocable<std::decay_t<TF>(Ts...), Ts...>{};
}
struct Test {};
int main()
{
std::cout << IS_VALID(std::ostream&, double)(_0 << _1) << std::endl;
std::cout << IS_VALID(std::ostream&, Test)(_0 << _1) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
但结果是:
1
1
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚为什么.
您的 lambda 按值获取参数,这不允许您测试std::ostream& << T. 将宏更改为:
#define IS_VALID_EXPANDER_BEGIN(count) \
[](BOOST_PP_REPEAT(count, IS_VALID_EXPANDER_MIDDLE, \
&&_)) constexpr->decltype IS_VALID_EXPANDER_END
Run Code Online (Sandbox Code Playgroud)
另外,你的使用is_invocable是错误的 - 它应该是:
template <typename... Ts, typename TF>
static constexpr auto is_valid(TF)
{
return boost::callable_traits::is_invocable<std::decay_t<TF>, Ts...>{};
}
Run Code Online (Sandbox Code Playgroud)
(std::is_invocable无论如何你都应该使用它,它在 C++17 中可用。)
| 归档时间: |
|
| 查看次数: |
271 次 |
| 最近记录: |