变体:没有匹配函数来调用' get'

时间:2017-08-28 11:21:34

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

这是我的代码:

#include <iostream>
#include <variant>
#include <vector>

class A {
public:
    virtual void Foo() = 0;    
};

class B : public A {
public:
    void Foo() override {
        std::cout << "B::Foo()" << std::endl;   
    }
};

class C :public A {
public:
    void Foo() override {
        std::cout << "C::Foo()" << std::endl;   
    }
};

template<typename... Args>
class D {
public:
    template<typename T>
    void Foo() {
        m_variant = T{};
    }

    void Bar() {
      std::get<m_variant.index()>(m_variant).Foo();
    }

private:
    std::variant<std::monostate, Args...> m_variant;
};

int main() {
    D<B, C> d;
    d.Foo<B>();
    d.Bar();

    d.Foo<C>();
    d.Bar();
}

(c.f wandbox.org

我收到错误no matching function for call to 'get',但我不知道原因。 std::variant::index()是constexpr,因此不是问题(我通过直接输入值1来测试,但仍然是同样的错误)。
我有一个std::monostate来阻止空变量(当typename... Args中没有args时)

2 个答案:

答案 0 :(得分:4)

m_variant.index()是运行时值(因为m_variant不是常量表达式。)

发送方式是使用访客,如:

std::visit([](auto& v) { v.Foo(); }, m_variant);

Demo

答案 1 :(得分:1)

标记为constexpr的东西告诉您在某些情况下可以在编译时调用它。 确保始终可以在编译时调用它。

我是variant的情况,index可以在编译时调用,如果变量本身是constexpr值。否则它是一个运行时方法。

您可以阅读有关何时可以在编译时调用某些内容的文档,或者对其进行推理;在这种情况下,如果变体的类型在运行时可能会有所不同,那么index如何成为编译时常量?请记住,只有值的ttpe和constexpr,以及它本身是否在编译时上下文中,可用于推理&#34;这可以在编译时调用&#34;。