使用特化器在模板类上正确使用const返回值

时间:2013-10-31 13:48:25

标签: c++ generic-programming

这是一个简短的模板类示例,我希望我的编译器拒绝:

struct Vector {
  Vector(float a, float b, float c): x(a), y(b), z(c) {}
  float x, y, z;
};

template <typename T>
class Field {
public:
  const T doSomething() const;
};

template <typename T>
const T Field<T>::doSomething() const {
  T out(0);
  return out;
}

template <>
const Vector Field<Vector>::doSomething() const {
  return Vector(1,2,3);
}

template <>
const float Field<float>::doSomething() const {
  return 0.0f;
}

int main() {
  Field<float> g;
  Field<Vector> h;
  g.doSomething();

  // This should be illegal!
  h.doSomething() = Vector(3,4,5);
}

编译器成功抛出错误!但是,让我假装我必须使用-Wall -Wextra进行编译,此代码会为此生成警告:

main.cpp:25:41: warning: type qualifiers ignored on function return type [-Wignored-qualifiers]

啊,所以你可以删除const返回类型上的doSomething()限定符,但这会在底部传递我的非法代码行。作为一个可能的解决方案,至少对于我的玩具问题,您可以编写通用doSomething()来处理原始类型,并且不会生成此警告,但是我必须专门化一个基本类型。有没有办法在不改变警告标志的情况下放弃此警告?

1 个答案:

答案 0 :(得分:0)

使用C ++ 11,您可以将赋值运算符限制为左值引用,如下所示:

struct Vector {
  Vector(float a, float b, float c): x(a), y(b), z(c) {}
  float x, y, z;
  Vector& operator=(const Vector&) & = default;
};

现在您可以从返回类型中删除const:

template <>
Vector Field<Vector>::doSomething() const {
  return Vector(1,2,3);
}

并且您的陈述仍然是错误:

error: no match for ‘operator=’ (operand types are ‘Vector’ and ‘Vector’)
   h.doSomething() = Vector(3,4,5);