How to efficiently initialize a std::variant data member in a class template
Consider the following class template, that can hold either a value of type T
or an instance of some ErrorInfo
class, using a std::variant
data member:
template <typename T>
class ValueOrError
{
private:
std::variant<T, ErrorInfo> m_var;
};
How can I efficiently initialize the variant T
alternative?
I can initialize it with a constructor like this:
template <typename T>
class ValueOrError
{
public:
explicit ValueOrError(const T& val)
: m_var{val} {}
…
};
But what syntax/coding technique can I use to enable move semantics optimization during initialization?
If I define a constructor taking a T&&
, should I std::move
or std::forward
the parameter into the m_var
?
template <typename T>
class ValueOrError
{
public:
// Efficient initialization with move semantics
explicit ValueOrError(T&& val)
: m_var{ /* ?? */ } {}
…
};
Note on interactions with ErrorInfo constructor overload
The ValueOrError
template should also have a constructor overload that takes an ErrorInfo
and initializes the variant member accordingly:
template <typename T>
class ValueOrError
{
public:
// Initialize with error code instead of T
explicit ValueOrError(const ErrorInfo& error)
: m_var{error} {}
…
};
It’s important that the generic T
constructor overload interacts properly with the specific ErrorInfo
overload.
ErrorInfo
is a tiny class that wraps an error code (e.g. a simple integer), and can be constructed from such error code:
class ErrorInfo
{
public:
explicit ErrorInfo(int errorCode)
: m_errorCode{errorCode}
{}
int ErrorCode() const
{
return m_errorCode;
}
// … other convenient methods
// (e.g. get an error message, etc.)
private:
int m_errorCode;
};
Comments
Post a Comment