Лязг предупреждение о побочных эффектах выражения


Дан следующий исходный код:

#include <memory>
#include <typeinfo>

struct Base {
  virtual ~Base();
};

struct Derived : Base { };

int main() {
  std::unique_ptr<Base> ptr_foo = std::make_unique<Derived>();

  typeid(*ptr_foo).name();

  return 0;
}

И скомпилировал его с помощью:

clang++ -std=c++14 -Wall -Wextra -Werror -Wpedantic -g -o test test.cpp

Настройка среды:

linux x86_64
clang version 5.0.0

Он не компилируется из-за предупреждения (примечание -Werror):

error: expression with side effects will be evaluated
      despite being used as an operand to 'typeid'
      [-Werror,-Wpotentially-evaluated-expression]
  typeid(*ptr_foo).name();

(просто Примечание: GCC не претендует на такого рода потенциальные проблемы)


Вопрос

Есть ли способ получить информацию о типе, на который указывает unique_ptr, не генерируя такого рода предупреждения?

Примечание: Я есть не говорить об отключении -Wpotentially-evaluated-expression или избегании -Werror.

2 5

2 ответа:

Похоже, что следующее должно работать без предупреждений и давать правильный результат для производного класса

std::unique_ptr<Foo> ptr_foo = std::make_unique<Bar>();

if(ptr_foo.get()){
    auto& r = *ptr_foo.get();
    std::cout << typeid(r).name() << '\n';
}

std::unique_ptr<T> имеет псевдоним типа std::unique_ptr<T>::element_type для T. Попробуйте следующее:

int main() 
{
  auto ptr_foo = std::make_unique<Foo>();

  typeid(decltype(ptr_foo)::element_type).name();

  return 0;
}