Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

candidate template ignored: couldn't infer template argument 'T' with std::variant

I’ve been reading all the other questions related to this error and could not find something suitable to my case (or I did not understood them correctly).

I present a minimal example of a class holding a std::variant which represents a variant value (the exception and error handling is omited for brevity):

#include <iostream>
#include <variant>
#include <string>

class Value {
    public:
        Value(const std::string&);
        Value(const int&);

        template<typename T> const T& GetValue() const;

    private:
        std::variant<int, std::string> m_value;
};

Value::Value(const std::string& val):m_value(val) {}
Value::Value(const int& val):m_value(val) {}

template<> const int& Value::GetValue<int>() const {
    return std::get<int>(m_value);
}

template<> const std::string& Value::GetValue<std::string>() const {
    return std::get<std::string>(m_value);
}

int main() {
    Value v_int { 666 };
    Value v_str { "Hola" };

    // int i = v_int.GetValue(); // ERROR
    int i = v_int.GetValue<int>(); // OK but not desireable
    // std::string s = v_str.GetValue(); // ERROR
    std::string s = v_str.GetValue<std::string>(); // OK but not desireable

    std::cout << "i: " << i << " s: " << s << std::endl;

    return 0;
}

What I don’t understand is why the // ERROR calls are not deductible if int and std::string are not convertible to each other and target variable destination is the correct type.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Even if manually calling GetValue<T> that would defy the purpose of the wrapping class.

Is calling the non explicit version even possible? Please, if possible do not limit to just present a solution but it would be appreciated an explanation of why it is not working so I can learn from my mistakes.

>Solution :

You might use conversion operator:

struct Wrapper{
    const std::variant<int, std::string>& m_value;

    operator int() const { return std::get<int>(m_value); }
    operator const std::string&() const { return std::get<std::string>(m_value); }    
};

class Value {
    public:
        Value(const std::string&);
        Value(const int&);

        auto GetValue() const
        {
            Wrapper w{m_value};
            return w;
        }

    private:
        std::variant<int, std::string> m_value;
};

Demo

But not sure it is a good idea.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading