c++ - 在具有专门化程序的模板类上正确使用 const 返回值

标签 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]

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

最佳答案

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

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

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

关于c++ - 在具有专门化程序的模板类上正确使用 const 返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19708308/

相关文章:

java - 如何返回一个泛型类型,同时将另一个泛型类型作为参数,两者都需要实现接口(interface)?

c - 定制树的复杂度顺序

c++ - 模板和循环依赖

c++ - 字符串作为指针与数组

c++ - 不明白为什么我不能在 QMainWindow 子类中调用 setCentralWidget

c++ - 为什么这段代码不能编译?

c++ - 定义 boost 压缩稀疏行图

c++ - Bresenham 画线算法

c++ - C++ 中的类前向声明

java - 为什么我通过将 Integer 类型参数设置为泛型中的 Integer 变量而出错?