有没有办法为模板类提供默认值?
E.g。假设我有一个类TimeSeries
,这是模板化的。我有一个名为Foo()
的函数,它返回T
。
template <typename T>
class TimeSeries
{
T foo();
}
我希望Foo()
进行一些计算并返回T
类型的内容。但是如果它不能,我希望它给出一个默认值。如果T
为double
,我希望它为NaN
。如果T
为int
,我希望它为0
。
TimeSeries<double> t;
t.foo(); // returns NAN
TimeSeries<int> t;
t.foo(); // returns 0
我将如何实现这一目标?
错误的解决方案是Foo()
采用默认值。
template <typename T>
class TimeSeries
{
T foo(T defaultValue)
{
T ret;
// if OK
ret = computeValue();
// if not OK
ret = defaultValue;
return ret;
}
}
因此默认值为0
或NaN
,具体取决于用户。
或者我首先要求设计有缺陷?
编辑 -
一个合乎逻辑的问题是询问如果T
不是int
或double
会发生什么。默认值甚至意味着什么?
我使用TimeSeries
,T
的方式并不完全是通用类型。它只能是int
,double
和string
中的一个。
我想过简单地编写3个单独的TimeSeries
类,但这似乎是一个有缺陷的方法。
我对其他想法持开放态度。
答案 0 :(得分:7)
您可以声明以下模板default_value<>
:
template<typename>
struct default_value;
然后,为int
和double
提供名为value
的成员的完整专精,该成员提供所需的默认值:
template<>
struct default_value<int> {
static constexpr int value = 0;
};
template<>
struct default_value<double> {
static constexpr double value = NaN;
};
然后,在foo
函数模板中,您只需返回该值:
return default_value<T>::value;
取决于T
。
答案 1 :(得分:3)
从C ++ 14开始,您可以使用variable template:
template <class T> constexpr T default_value = {};
template <>
constexpr double default_value<double> = std::numeric_limits<double>::quiet_NaN();
template <typename T> class TimeSeries
{
auto foo() -> T
{
T ret;
if (condition)
return ret;
else
return default_value<T>;
}
};
答案 2 :(得分:1)
或者我首先要求设计有缺陷?
就我而言,它是一个有效的要求。
我认为有两种方法可以解决这个问题。
您可以按the other answer中的建议使用std::optional
方法。
如果您可以选择使用C ++ 17,则可以使用std::optional
。
如果您不能选择使用C ++ 17,则可以通过将返回值更改为std::pair<boo, T>
并以first
为基础,以不太复杂的方式模拟false
true
如果计算不成功,则返回值的{1}}设置为{{1}},如果计算成功,则返回{{1}}。
就个人而言,我更喜欢第二种解决方案。它不依赖于哨兵值。它以清晰明确的方式捕获计算是否成功的状态。