C++ 关于表情副作用的叮当警告

C++ 关于表情副作用的叮当警告,c++,clang++,typeid,C++,Clang++,Typeid,给定以下源代码: #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

给定以下源代码:

#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;
}
由于警告,它无法编译(注意
-Werror
):

(请注意:GCC并未声称存在此类潜在问题)


问题

有没有一种方法可以在不生成此类警告的情况下获取由
唯一\u ptr
指向的类型的信息


注意:我不是说禁用
-Wpotentially evaluated expression
或避免
-Werror

看起来以下内容应该在没有警告的情况下工作,并为派生类提供正确的结果

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 ptr_foo=std::make_unique();
if(ptr_foo.get()){
auto&r=*ptr_foo.get();

std::请注意,在这种情况下,clang是正确的,警告是有帮助的,因为您可能不希望
typeid
调用实际有任何副作用。@Rakete1111-抱歉,迟到了。我们到底在谈论什么副作用?显然,我想要从方法链返回值,因为我编写了它们。@Gem
typeid
是唯一一个这样做的表达式。
decltype
sizeof
不计算任何值。根本没有单行解决方案吗?我在断言中使用了类似的表达式,该表达式仅用于内部构建,因此不需要临时值。您可以将临时值放入函数参数中:
template string get_name(const T&v){return typeid(v).name()}ASSERT(get_name(*ptr_foo)==“foo”)
我遇到了同样的问题,由于您的解决方案,我用这个小模板助手解决了这个问题:
模板char const*str_type(T const&obj){return typeid(obj).name()
。作为一个不错的奖励,它比最初的召唤要短得多,但是,它只对有效的指针有效(否则,这会取消null ptr,但很容易避免)。有什么解释吗?为什么直接使用typeid(*ptr_foo.get()).name()“Error”不工作?“Error”,因为人们大多认为 Type ID >代码>不计算表达式。对于返回多态对象的表达式,编译器必须生成代码来评估表达式。它是有效的C++代码(所以GCC不警告)。,但人们可能没有意识到后果。发生这种情况时,Clang会发出警告。这些解决方案都在typeid之外进行表达式求值,编译器和人类读者都应该看到这一点。
error: expression with side effects will be evaluated
      despite being used as an operand to 'typeid'
      [-Werror,-Wpotentially-evaluated-expression]
  typeid(*ptr_foo).name();
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';
}