【问题标题】:Default value for Template Class, C++模板类的默认值,C++
【发布时间】:2018-07-15 14:03:33
【问题描述】:

有没有办法为模板类提供默认值?

例如假设我有一个类TimeSeries,它是模板化的。我有一个名为Foo() 的函数,它返回T

template <typename T>
class TimeSeries
{
    T foo();
}

我想让Foo() 做一些计算并返回T 类型的东西。但万一它不能,我希望它给出一个默认值。如果Tdouble,我希望它是NaN。如果Tint,我希望它是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;
    }
}

因此默认值为0NaN,具体取决于用户。

还是我一开始就要求有缺陷的设计?

编辑 - 一个合乎逻辑的问题是询问如果T 不是intdouble 会发生什么。默认值是什么意思?

我使用TimeSeriesT 的方式并不完全是通用类型。它只能是 intdoublestring 中的 1 个。 我想过简单地编写 3 个单独的 TimeSeries 类,但这似乎是一种有缺陷的方法。

我对其他想法持开放态度。

【问题讨论】:

  • 可以通过多种方式完成。最简单的是if constexpr (std::is_integral_v&lt;T&gt;) return 0; else return NAN;
  • 如果T 不是doubleint,那么默认值是多少?
  • 我设想TimeSeries 不完全是一个通用类。按照我的使用方式,它只会是TimeSeries&lt;double&gt;TimeSeries&lt;int&gt;,也许还有TimeSeries&lt;std::string&gt;。当然,我本可以编写 3 个单独的 TimeSeries 类,但我觉得那会是一个更奇怪的解决方案。

标签: c++ templates


【解决方案1】:

从 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 中的建议使用default_value 方法。

    2. 如果你有使用 C++17 的选项,你可以使用std::optional

      如果您没有使用 C++17 的选项,您可以通过将返回值更改为 std::pair&lt;boo, T&gt; 以不太复杂的方式模拟 std::optional,但要了解返回值的 first如果计算不成功则设置为false,如果计算成功则设置为true

    就个人而言,我更喜欢第二种解决方案。它不依赖哨兵值。它以清晰明确的方式捕获计算是否成功的状态。

    【讨论】:

      【解决方案3】:

      您可以声明以下模板,default_value&lt;&gt;

      template<typename>
      struct default_value;
      

      然后,为 intdouble 提供完整的特化,并使用名为 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

      猜你喜欢
      • 2011-03-19
      • 1970-01-01
      • 2011-10-26
      • 1970-01-01
      • 2011-07-15
      • 1970-01-01
      • 2016-10-28
      • 2018-10-12
      • 1970-01-01
      相关资源
      最近更新 更多