GCC -Weffc ++运算符重载返回`* this`和CRTP

时间:2015-10-20 16:55:12

标签: c++ gcc compiler-warnings crtp effective-c++

Scott Meyers' Effective C ++ 建议赋值运算符应返回对*this的引用。 GCC的-Weffc++似乎概括了这个原则,以建议就地算术运算符的重载(例如前缀++)也应该返回对类类型实例的引用。

但对于CRTP,GCC显然无法识别正在返回正确的引用类型:

template <typename DERIVED>
class Foo
{
  public:
    DERIVED& operator++(void)
    {
      ++data;
      return static_cast<DERIVED&>(*this);
    }

  private:
    int data;
};

class Bar : public Foo<Bar>
{  /* ... */ };

在这里,DERIVED&是真正应该返回的类型,因为Bar而不是Foo<Bar>是&#34;真实&#34; Bar实例的类型。但GCC发出以下警告:

operator_return_this.cpp:5:33: warning: prefix ‘DERIVED& Foo<DERIVED>::operator++()’ should return ‘Foo<DERIVED>&’ [-Weffc++]
         DERIVED& operator++(void)
                                 ^
operator_return_this.cpp: In instantiation of ‘class Foo<Bar>’:
operator_return_this.cpp:15:24:   required from here
operator_return_this.cpp:5:18: warning: prefix ‘DERIVED& Foo<DERIVED>::operator++() [with DERIVED = Bar]’ should return ‘Foo<Bar>&’ [-Weffc++]
         DERIVED& operator++(void)

第一个警告有点明智 - 编译器无法告诉该类是否打算用于CRTP,因此它没有意识到DERIVED将继承自{{1} }}。 (编辑:实际上,通过使用Foo<DERIVED>代替C风格的广告,你确保static_cast确实是派生类型,因此,如果编译器推迟发出此警告,直到查看该函数的实现,即使没有看到DERIVED的定义,它也可以抑制误报。)但是第二个警告,它在哪里看到实际的CRTP声明,对我来说根本没有意义,因为它能够告诉我Bar计为Bar&

但是当使用CRTP和运算符重载时,即使是第一个警告也是假的。这是否意味着Foo<Bar>&无法与CRTP一起使用(假设您想避免虚假警告)?

0 个答案:

没有答案