首页 > 解决方案 > 使用可变参数模板化帮助器的多个 std::variant 访问

问题描述

我正在尝试制作一个有助于处理 Nstd::variant类型的函数。

注意:我正在尝试验证所有路径的编译时间。所以对我std::optional来说std::holds_alternative是不可行的。

实现如下:

template<typename T>
using Possible = std::variant<std::monostate, T>;

template<typename... Types>
void ifAll(std::function<void(Types...)> all, Possible<Types>&&... possibles)
{
    std::visit(
        [&](auto&&... args) {
            if constexpr ((... &&
                           std::is_same_v<std::decay_t<decltype(args)>, Types>))
            {
                return all(std::forward<Types>(args)...);
            }
            else
            {
                std::cout << "At least one type is monostate" << std::endl;
            }
        },
        possibles...);
}

使用该功能的一个例子是:

int main()
{
    Possible<int>  a = 16;
    Possible<bool> b = true;

    ifAll([](const int& x, const bool& y)
              -> void { std::cout << "All types set!" << std::endl; },
          a,
          b);
}

但是我得到一个编译器错误:

TestFile.cc: error: no matching function for call to 'ifAll'
    ifAll([](const int& x, const bool& y)
    ^~~~~

TestFile.cc: note: candidate template ignored: could not match
    'function<void (type-parameter-0-0...)>' against '(lambda at
    TestFile.cc)'

void ifAll(std::function<void(Types...)> all, Possible<Types>&&... possibles)
    ^

为什么我提供的 lambda 与函数签名不匹配?

尝试修复 1

我尝试搬进去ab但仍然无法正常工作:

ifAll([](const int& x, const bool& y)
              -> void { std::cout << "All types set!" << std::endl; },
          std::move(a),
          std::move(b));

标签: c++templatesc++17variadic-templates

解决方案


以下电话将起作用:

int main() {
    Possible<int>  a = 16;
    Possible<bool> b = true;

    std::function<void(int, bool)> fun = [](int x, bool y) -> void {
        std::cout << "All types set!" << std::endl;
    };

    ifAll(fun,
          std::move(a),
          std::move(b));
}

或将您的函数签名切换为:

template <typename... Types>
void ifAll(std::function<void(Types...)> const& all, Possible<Types>&... possibles)

然后你可以在没有的情况下调用它std::move

int main() {
    Possible<int>  a = 16;
    Possible<bool> b = true;

    std::function<void(int, bool)> fun = [](int x, bool y) -> void {
        std::cout << "All types set!" << std::endl;
    };

    ifAll(fun, a, b);
}

推荐阅读