简体   繁体   中英

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

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;
}

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

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 can look something like:

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

Now you can use:

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

variant::operator= will invoke the constructor to construct the alternative type, so you need to provide the corresponding constructor for StackStringHolder

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM