gpt4 book ai didi

c++ - 如何在类模板中有效地初始化 std::variant 数据成员

转载 作者:行者123 更新时间:2023-12-02 18:07:29 25 4
gpt4 key购买 nike

考虑以下类模板,它可以使用 std::variant< 保存 T 类型的值或某个 ErrorInfo 类的实例 数据成员:

template <typename T>
class ValueOrError
{
private:
std::variant<T, ErrorInfo> m_var;
};

如何有效初始化变体T替代方案?

我可以用这样的构造函数初始化它:

template <typename T>
class ValueOrError
{
public:
explicit ValueOrError(const T& val)
: m_var{val}
{
}


};

但是我可以使用什么语法/编码技术来在初始化期间启用 move 语义优化?

如果我定义一个采用 T&& 的构造函数,我应该将 std::movestd::forward 参数放入 >m_var

template <typename T>
class ValueOrError
{
public:
// Efficient initialization with move semantics
explicit ValueOrError(T&& val)
: m_var{ /* ?? */ }
{
}


};

与 ErrorInfo 构造函数重载交互的注意事项

ValueOrError 模板还应该有一个构造函数重载,它接受 ErrorInfo 并相应地初始化变体成员:

template <typename T>
class ValueOrError
{
public:
// Initialize with error code instead of T
explicit ValueOrError(const ErrorInfo& error)
: m_var{error}
{
}


};

通用 T 构造函数重载与特定 ErrorInfo 重载正确交互非常重要。

ErrorInfo 是一个封装错误代码(例如简单整数)的小类,并且可以从这样的错误代码构造:

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

最佳答案

使用 perfect forwarding 的 C++20 版本:

#include <concepts> // std::constructible_from

template <class T>
class ValueOrError {
public:
explicit ValueOrError(const ErrorInfo& error) : m_var{error} {}

template<class... Args>
requires std::constructible_from<T, Args...>
explicit ValueOrError(Args&&... val) :
m_var(std::in_place_type<T>, std::forward<Args>(val)...)
{}

private:
std::variant<T, ErrorInfo> m_var;
};

同样使用完美转发的 C++17 版本可能如下所示:

#include <type_traits>  // std::is_constructible_v, std::enable_if_t

template <class T>
class ValueOrError {
public:
explicit ValueOrError(const ErrorInfo& error) : m_var{error} {}

template<class... Args,
std::enable_if_t<std::is_constructible_v<T, Args...>, int> = 0>
explicit ValueOrError(Args&&... val)
: m_var(std::in_place_type<T>, std::forward<Args>(val)...) {}

private:
std::variant<T, ErrorInfo> m_var;
};

用法示例:

class foo { // A non default constructible needing 3 constructor args
public:
foo(double X, double Y, double Z) : x(X), y(Y), z(Z) {}
private:
double x, y, z;
};

int main() {
ValueOrError<foo> voe1(1., 2., 3.); // supply all three arguments

// use the string constructor taking a `const char*`:
ValueOrError<std::string> voe2("Hello");

std::string y = "world";
// use the string constructor taking two iterators:
ValueOrError<std::string> voe3(y.begin(), y.end());
}

关于c++ - 如何在类模板中有效地初始化 std::variant 数据成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72953783/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com