这是一个简短的模板类示例,我希望我的编译器拒绝它:
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/