C ++:如何在类和基元上使用模板?

时间:2011-06-03 21:01:27

标签: c++ templates reference

我有一个关于模板的问题,这些模板可以用于类或基本类型的参数。这是一些示例代码:

(注意:我的实际代码更复杂,下面的代码没用,但它会重现相同的问题)

template<typename T>
class Foo
{
  T value;

public:
  Foo() {}
  const T& getValue() const { return value; }
  Foo& setValue(const T& other) { 
    value = other; return *this; 
  }
};

struct Bar
{
  int x;

  Bar() : x(3) {}
};

int doit()
{
  Foo<int> fooint;
  Bar bar;
  bar.x = 44;
  Foo<Bar> foobar;

  fooint.setValue(3);      // warning here
  foobar.setValue(bar);

  int y = foobar.getValue().x + fooint.getValue();
  return y;
}

我在fooint.setValue()上收到编译器评论:

value copied to temporary, reference to temporary used

我理解这句话。我想知道的是,如果我要将Foo与原语和类/结构类型一起用作模板参数,我应该如何处理Foo::setValue()

我认为setValue(const T& other)是通过引用传递常量类的正确方法签名。

有没有办法让setValue()为Foo<int>Foo<Bar>做“正确的事”?

4 个答案:

答案 0 :(得分:8)

将临时值绑定到const引用是完全合法的,就像在setValue()中一样。发布此评论的英特尔C ++在这种情况下没有用处。

编辑:我猜测TI编译器基于英特尔,对我来说,它在该行上发布了以下诊断:

test.cc(28): remark #383: value copied to temporary, reference to temporary used
    fooint.setValue(3);      // warning here

诊断在http://software.intel.com/en-us/articles/cdiag383/讨论

  

可以安全地忽略此向量的回退功能警告。向量将参数复制到自己的存储中;它从不存储原始论点。因此,使用临时安全是非常安全的。

在你的情况下,你也在复制参数,因此它也可以被忽略。

答案 1 :(得分:1)

我发现您的代码没有任何问题。 GCC编译它没有错误或警告。

答案 2 :(得分:1)

要回答关于让Foo<T>::setValue()做'正确的事'的最后一个问题,你可以考虑使用模板专门化来实现这一点 - 这是模板元编程中常用的一种技术。像这样的东西:

template <typename T>
struct Ref_or_Value
{
    typedef T& type;
};

template <typename T>
struct Ref_or_Value<T *>
{
    typedef T* type;
};

template <>
struct Ref_or_Value<int>
{
    typedef int type;
};

// add other primitive types like above as need

然后Foo<T>::setValue签名变为:

Foo& setValue(const typename Ref_or_Value<T>::type other);

这是否过度杀戮我会让你决定,但这应该让setValue做'正确的事'。如果T=int则setValue将按值获取参数。如果T=Foobar_object那么它将通过const引用。

答案 3 :(得分:0)

在Visual Studio 2010上不会对我产生任何警告/错误。您的编译器显示诊断是非常奇怪的,因为它没有意义。 3是一个右值,并且明确允许rvalues绑定到const int&之类的常量引用。