Скотт Мейерс Эффективный C ++ рекомендует, чтобы операторы присваивания возвращали ссылку на *this
, ССЗ -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>
это «реальный» тип экземпляра 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
унаследует от Foo<DERIVED>
, (РЕДАКТИРОВАТЬ: На самом деле, используя static_cast
вместо броска в стиле C, вы делать убедиться, что DERIVED
на самом деле является производным типом, поэтому, если компилятор отложил выдачу этого предупреждения до просмотра реализация функции, он может подавить ложное срабатывание, даже не видя определения Bar
.) Но второе предупреждение, где оно видит фактическую декларацию CRTP, вообще не имеет смысла, так как оно должен быть в состоянии сказать, что Bar&
считается как Foo<Bar>&
,
Но при использовании CRTP с перегрузкой оператора даже первое предупреждение является ложным. Значит ли это, что -Weffc++
просто не может быть использован с CRTP (если вы хотите избежать ложных предупреждений)?
Задача ещё не решена.
Других решений пока нет …