9

出于教育目的,我正在编写自己的 C++ 数值向量模板类。我希望能够为两个向量的点积编写 (v, w) 并因此重载operator,()如下:

template<class T>
const T Vector<T>::operator,(const Vector<T>& v) const
{
    assertEqualSize(v);

    T t;
    for(size_t i=0; i<numElements; i++) {
        t += elements[i] * v[i];
    }
    return t;
}

我现在的问题是:如何正确初始化t一个合理的值(例如0.0for Vector<double>)?我试过T t();了,但是 g++ 告诉我,例如,“double(*)()”不能在 return 语句中转换为“const double”,并且operator+=()不会为“(double(), double)”定义。

非常感谢你!

4

2 回答 2

9

您需要的是值初始化,它具有零初始化内置类型的效果:

T t{};     // C++11
T t = T(); // C++03 and C++11

这不起作用的原因

T t();

是它是一个名为 的无参数函数的声明t,返回一个T.

于 2013-08-08T07:17:35.410 回答
0

当简单的值初始化调用默认构造函数并因此可能无法进行零初始化时,您的代码确实允许任何类型T,包括用户定义的类型。如果您的意图不是内置类型,我会感到惊讶,但您的代码的用户可能有其他想法......您应该防范这种情况,例如通过 SFINAE:T

template<class T>
struct is_complex { static const bool value = false; };
template<class U>
struct is_complex<std::complex<U>> : std::is_floating_point<U> {};

template<class T>
typename
std::enable_if<std::is_floating_point<T>::value || is_complex<T>::value,
               T>::type
T Vector<T>::operator,(const Vector<T>& v) const
{
   T t{};  // value-initialisation is now guaranteed to be zero-initialisation
   /* ... */
}

当然,这种类型的 SFINAE 可以应用于class Vector<T>整体(而不是将其应用于选定的方法)。


澄清一下:这基本上将可能的类型限制T为仅 6 种允许的类型(floatdoublelong double和相应的std::complex<>类型)。当然,可以允许整数类型,但如果您想要整数向量的向量运算,我会感到惊讶。

于 2013-08-08T10:05:48.690 回答