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

发布于 2024-10-22 07:09:48 字数 1068 浏览 1 评论 0原文

因此,在编写 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,则 T value; 行将使用 的默认构造函数初始化 value >SomeClass

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

    T GetFoo()
    {
        T value = T();

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

        return value;
    }

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

So in writing a C++ template class, I have defined a method that returns an object of the templated type, as such:

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;
}

This gives the following warning:

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

I understand why this is happening - I am returning an uninitialized int as part of GetFoo. The thing is, if I were to use Foo<SomeClass>, the line T value; would initialize value using the default constructor of SomeClass.

I have managed to suppress this warning by doing the following:

    T GetFoo()
    {
        T value = T();

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

        return value;
    }

This seems to work for primitive types (such as int and float) and classes, at least so long as that class has a default constructor and copy constructor. My question is - is this the accepted way of solving this problem? Are there any side effects of this I should know about?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

黒涩兲箜 2024-10-29 07:09:48

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

Sounds OK, if the class has no copy constructor, you will not be able to return it anyway.

棒棒糖 2024-10-29 07:09:48

Default行

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;
}

请参阅 < a href="http://codepad.org/w15PqPLu" rel="nofollow">键盘。

The line

T t;

Default constructs objects, yet declares uninitialized built-in types. There is no syntax to 'default construct' a local variable.

Therefore it's not trivial to write generic code that initializes a variable, whether built-in or class.

Wrapping the type into a member variable, however, may present a workaround that does not need copy construction (apart from the return statement):

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

Using this wrapper, you can build your code in a generic way:

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

See a full-blown snippet at codepad.

锦上情书 2024-10-29 07:09:48

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

Indeed that's the standard way to solve the problem. I don't believe there should be any side effects to worry about in this case.

天涯沦落人 2024-10-29 07:09:48

您真的想从此函数返回未初始化的值吗?听起来这可能会导致以后出现很多垃圾。

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

Do you really want to return an un-initialized value from this function? Sounds like it could lead to a whole lot of crap later down the line.

Why don't you use an appropriate wrapper - if you have access to boost, consider boost::optional. This way, if you don't initialize it, it can be tested properly.

巡山小妖精 2024-10-29 07:09:48

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

对于类来说,不仅需要 [public] 复制构造函数,还需要 public 默认构造函数!

我的问题是 - 这是解决这个问题的公认方法吗?

通常最好提供 public 默认构造函数。 STL容器一直在使用它!如果您没有一个,大多数(或者可能是全部)STL 容器在很多情况下都无法工作。

请参阅此示例,其中使用 private 默认构造函数:http://ideone.com/EdPLu

This seems to work for primitive types
(such as int and float) and classes,
at least so long as that class has a
copy constructor

For classes, not only [public] copy-constructor, you also need public default constructor!

My question is - is this the accepted way of solving this problem?

Usually it's a good idea to provide public default constructor. STL containers use it all the time! If you don't have one, most (or maybe, all) STL containers would not work at many occasions.

See this example with private default constructor: http://ideone.com/EdPLu

思慕 2024-10-29 07:09:48

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

Boost addresses this problem in one of its utility template classes, namely boost::value_initialized and its relatives.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文