c++ - 如何将当前替代类型的 std::variant 传递给可调用对象?

标签 c++ c++17 std-variant

我正在使用在运行时确定的参数调用一些用户定义的可调用对象。 我有以下工作:

using argument_t = std::variant< int, bool, double, std::string >;
using argument_list = std::vector< argument_t >;

template < typename Callable, std::size_t... S >
auto invoke_with_args_impl( Callable&& method, const argument_list& args, std::index_sequence< S... > )
{
    return std::invoke( method, args[S]... );
}

template < std::size_t size, typename Callable >
auto invoke_with_args_impl( Callable&& method, const argument_list& args )
{
    if ( args.size() != size )
    {
        throw std::runtime_error( "argument count mismatch" );
    }
    return invoke_with_args_impl( std::forward< Callable >( method ), args, std::make_index_sequence< size >() );
}

template < typename Callable >
auto invoke_with_args( Callable&& method, const argument_list& args )
{
    switch ( args.size() )
    {
        case 0:
            return method();
        case 1:
            return invoke_with_args_impl< 1 >( std::forward< Callable >( method ), args );
        //.... ad nauseam

一切正常,但是,argument_t 必须是用户定义函数中所有参数的类型才能成功运行。

我正在尝试弄清楚如何传递变体的当前替代类型。

有点像

return std::invoke( method, std::get< args[S].index() >( args[S] )... );

但显然这行不通......不幸的是,我在这方面的技能已经到了尽头。

如何做到这一点?

最佳答案

你可以使用类似的东西:

template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;

template < typename Callable, std::size_t... Is >
auto invoke_with_args_impl(Callable&& method,
                           const argument_list& args,
                           std::index_sequence<Is...>)
{
    return std::visit(overloaded{
        [&](auto&&... ts)
        -> decltype(std::invoke(method, static_cast<decltype(ts)>(ts)...))
        { return std::invoke(method, static_cast<decltype(ts)>(ts)...); },
        [](auto&&... ts)
        -> std::enable_if_t<!std::is_invocable<Callable, decltype(ts)...>::value>
        { throw std::runtime_error("Invalid arguments"); } // fallback
      },
      args[Is]...);
}

Demo

关于c++ - 如何将当前替代类型的 std::variant 传递给可调用对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57621204/

相关文章:

c++ - 为什么在使用 libc++ 时 sizeof( std::variant< char > ) == 8 而不是 2 (如 MSVC 的 STL 和 libstdc++)?

c++ - 是否有插入函数定义的快捷键?

c++ - "template argument deduction for class templates"是否应该为可变类模板推导出空参数包?

c++ - g++ std::variant 似乎无法支持具有 std::atomic/std::mutex 变量成员的用户类(带有详细信息/代码)

c++ - 解决 CRTP 函数重载歧义

c++ - 字符串比较在与变量一起使用时给出不同的输出

c++ - 如何在带有访问者的lambda中调用std::visit,访问者是按值捕获的函数对象

c++ - C++编写的分词器的继承设计

c++ - [C++] 将一个字符串分割成由另一个字符串中给出的符号以外的任何分隔符分隔的字符串?

c++ - 二进制表达式 ('double(*)(double' 和 'double' 的无效操作数)