带有默认值的模板返回类型

时间:2011-03-14 15:19:51

标签: c++ templates

因此,在编写C ++模板类时,我已经定义了一个返回模板化类型对象的方法,如下所示:

template <typename T>
class Foo
{
public:
    T GetFoo()
    {
        T value;

        //Do some stuff that might or might not set the value of 'value'

        return value;
    }
 };

int main() {

    Foo<int> foo;

    foo.GetFoo();

    return 0;
}

这会发出以下警告:

prog.cpp: In member function ‘T Foo<T>::GetFoo() [with T = int]’:
prog.cpp:15: warning: ‘value’ is used uninitialized in this function

我理解为什么会这样 - 我正在int作为GetFoo的一部分返回未初始化的Foo<SomeClass>。问题是,如果我使用T value;,则行value将使用SomeClass的默认构造函数初始化 T GetFoo() { T value = T(); //Do some stuff that might or might not set the value of 'value' return value; }

我设法通过执行以下操作来抑制此警告:

int

这似乎适用于原始类型(例如float和{{1}})和类,至少只要该类具有默认构造函数和复制构造函数。我的问题是 - 这是解决这个问题的公认方式吗?我应该知道这有什么副作用吗?

6 个答案:

答案 0 :(得分:5)

听起来不错,如果该类没有复制构造函数,那么无论如何都无法返回它。

答案 1 :(得分:3)

确实,这是解决问题的标准方法。我认为在这种情况下不应该担心任何副作用。

答案 2 :(得分:3)

该行

T t;

默认构造对象,但声明未初始化的内置类型。 “默认构造”局部变量没有语法。

因此,编写初始化变量的通用代码(无论是内置函数还是类函数)并非易事。

然而,将类型包装到成员变量中可能会提供一种不需要复制构造的解决方法(除了return语句):

template< typename T > struct Initializer {
   T t;
   Initializer()
   :t() // ====> default construction, works for classes _and_ built-in
   {}
};

使用此包装器,您可以以通用方式构建代码:

template<typename T> T foo() {
  Initializer<T> i;
  // fill in i.t to your liking
  return i.t;
}

codepad查看完整的摘录。

答案 3 :(得分:1)

  

这似乎适用于原始类型   (例如int和float)和类,   至少只要该班有一个   复制构造函数

对于类,不仅是[public] copy-constructor,还需要public默认构造函数!

  

我的问题是 - 这是解决这个问题的可接受方式吗?

通常提供public默认构造函数是个好主意。 STL容器一直使用它!如果你没有,大多数(或许是全部)STL容器在很多情况下都不会起作用。

使用private默认构造函数http://ideone.com/EdPLu

查看此示例

答案 4 :(得分:1)

你真的想从这个函数返回一个未初始化的值吗?听起来这可能导致后来发生了很多废话。

为什么不使用合适的包装器 - 如果您有权访问boost,请考虑boost::optional。这样,如果你没有初始化它,它可以正确测试。

答案 5 :(得分:0)

Boost在其实用程序模板类中解决了这个问题,即boost::value_initialized及其亲属。