How to call proper assignment operator of custom class inside std::variant

Viewed 89

I have the following class:

class StackStringHolder
{
public:
    StackStringHolder& operator=(const std::string& str)
    {
        str_ = str;
        return *this;
    }
    StackStringHolder& operator=(std::string&& str)
    {
        str_ = std::move(str);
        return *this;
    }
    const std::string& get() const { return str_; }

private:
    std::string str_;
};

And I want to use it in the std::variant the following way:

int main() {
    std::variant<int, StackStringHolder> var;
    var = 5;
    std::string str = "Hello";
    var = str; // error
    var = std::move(str); // error
}

However compiler (MSVS2022) says:

error C2679: binary '=': no operator found which takes a right-hand operand of type 'std::string' (or there is no acceptable conversion)

Update, I'm sure my pieces of code enough, but as I'm asked for, here is the complete example:

#include <string>
#include <variant>

class StackStringHolder
{
public:
    StackStringHolder& operator=(const std::string& str)
    {
        str_ = str;
        return *this;
    }
    StackStringHolder& operator=(std::string&& str)
    {
        str_ = std::move(str);
        return *this;
    }
    const std::string& get() const { return str_; }

private:
    std::string str_;
};

int main() {
    std::variant<int, StackStringHolder> var;
    var = 5;
    std::string str = "Hello";
    var = str; // error
    var = std::move(str); // error

    return 0;
}
1 Answers

The Cause of the Problem:

Your var can hold either an int or a StackStringHolder, so you cannot trivially assign it with a std::string.

Solution:

You can however add a converting constructor to your class StackStringHolder which accepts a std::string.
Then it can be used to convert str to StackStringHolder and assign it to var.

Your converting constructor should look something like:

StackStringHolder(std::string const& str)
    : str_(str)  {}

Now you can use:

var = str;
var = std::move(str);
Related