模板类中的设置程序
Setters in template classes
我正试图找到一种为模板类编写setter函数的好方法。对于非模板类,如果因为函数签名/实现取决于参数类型而显得微不足道。例如,如果参数类型为int
,则下一个函数应该是最优的:
void MyClass::Set(int value)
{
myValue = value;
}
如果参数类型是std::vector
,那么下一个实现应该接近最优:
void MyClass::Set(std::vector<SomeType> value)
{
std::swap(myValue, value);
}
由于将使用正确的构造函数(move或copy)来构造函数参数,并且不会发生不必要的复制,因此假设move构造函数的成本可以忽略不计。
正如您所看到的,当类型更改时,这两种实现都有缺点:如果第一个版本的类型更改为std::vector
,则至少会制作一个不必要的副本,从而使实际成本增加2或3倍。如果在第二版本中将类型更改为int
,则会进行2次不必要的复制,从而将实际成本增加3倍。
你能给我一个setter函数的好的通用实现吗(可能有重载)?对于用作参数的任何类型,它都应该是最优的/接近最优的
PS:我宁愿不使用std::enable_if
来制作几个依赖于类型的setter,因为类会急剧增加。
您可以使用转发引用接受右值或左值template <typename T>
void Set(T && value) {
myValue = std::forward<T>(value);
}
您应该有3个重载。
void Set( T&& t ) {
v = std::move(t);
}
void Set( T const& t ) {
v = t;
}
template<class U>
void Set( U&& u ) {
v = std::forward<U>(u);
}
如果调用方对参数使用{}
初始化,或者调用方是函数的名称并且需要上下文,或者在其他一些情况下,前两种方法允许隐式转换很好地工作:它会工作。这通过"完美转发"解决了一些更大的烦恼。
第三种方法为operator=
提供了前两种方法没有涵盖的重载处理。这是"完美转发"的一个例子,顾名思义,这是不完美的。
如果只使用第三个过载,最常见的问题是.Set( {construction args} )
不起作用。
const&
过载可能是多余的,但我不确定。
实例
// and sometimes:
template<class...Us>
void Set( Us&&...us ) {
v = {std::forward<Us>(us)...};
}
第四个是模板集。在这种情况下(我们使用operator=
),这实际上并不有用,但在某些情况下可能有用。例如,这种模板访问器有用,optional::value_or
应该具有该重载。基本上,在您可以直接构造目标值的情况下,或者在其他参数可能导致您而不是构造值的情况中,这是有用的:如果您总是执行{std::forward<Us>(us)...}
,那么您还可以从外部使用.Set( {args...} )
,它调用上面的第一个重载。
- 有可能在信号处理程序中设置promise吗
- 如何在提升程序选项中设置矢量<矢量>的默认值<string>
- 设置我的应用程序 API 感知并防止系统使其模糊和错误定位
- 我可以对 2 个或更多应用程序进行 QSettings 设置吗?
- 如何设置Qt应用程序以使用类Unix系统的实际环境变量?
- 适用于 macOS 的 Xcode 应用程序。这就是我设置从USB麦克风输入获取音频的方式。一年前工作,现在没有了。为什么
- 设置变量时C++程序挂起
- 如何将从控制台应用程序C++回调设置为C++ COM DLL
- 使用代码在 AWS 开发工具包C++控制台应用程序上设置凭证
- 如何设置一个简单的CGAL+Qt程序
- PyFunctionObject 在 Py_Finalize 中使程序崩溃,如果它在 PyTuple 中被设置了项目
- Haskell堆栈设置 - 无法识别CPP程序
- 如何使用CMake在Windows上将应用程序入口点设置为main()C++?
- 模板类中的设置程序
- 设置程序可以生成的进程数限制
- 如何正确设置程序变量
- 如何在源代码中设置程序执行的优先级
- 使用Win32 API设置程序描述和公司名称
- 使用WIN32 API在没有资源的情况下设置程序图标
- 如果这在C++设置程序中使用,有关系吗