1

Here's a short template class example which I want my compiler to reject:

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

The compiler successfully throws an error! However, let's pretend I have to compile with -Wall -Wextra, for which this code generates the warning:

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

Ah, so you could remove the const qualifier on doSomething()'s return type, but that would pass my illegal line of code at the bottom. As a possible solution at least for my toy problem you can probably write the generic doSomething() to handle the primitive types and this warning is not generated, but say I have to specialize a primitive type. Is there a way to drop this warning short of altering the warning flags?

4

1 に答える 1

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

あなたのステートメントはまだエラーです:

エラー: 'operator=' に一致しません (オペランドの型は 'Vector' と 'Vector' です)
   h.doSomething() = ベクトル(3,4,5);
于 2013-10-31T14:11:40.183 に答える