C++ 17检查有效表达式

chi*_*ila 5 c++ c++17

此基础上我的代码这个这个,我已经写了这个版本:

#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)

我无法弄清楚为什么.

Vit*_*meo 2

您的 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 中可用。)

wandbox.org 上的实例