【问题标题】:Why does this compiler warning only show for int but not for string? "type qualifiers ignored on function return type"为什么这个编译器警告只显示 int 而不是 string? “在函数返回类型上忽略类型限定符”
【发布时间】:2021-08-15 22:54:29
【问题描述】:

我对使用 mingw64 编译 C++11 代码时收到的一些警告感到有些困惑。这是我的 MWE:

class A{
    const string name;
    const int ID;

    public:
        A(string name_, int ID_) : name(name_), ID(ID_){
            // initialize non-const members
        }
        const string getName() const{return name;}
        const int getID() const{return ID;}
};

int main()
{   
    A aObj = A("Aname", 1);
    std::cout << "getName() = " << aObj.getName() << std::endl;
    std::cout << "getID() = " << to_string(aObj.getID()) << std::endl;
}

代码可以正常执行,但我收到了编译器警告:

,,localtest.cpp:10:9: 警告:函数返回类型忽略类型限定符

[-Wignored-qualifiers] const int getID() const{返回 ID;}

所以警告只显示getID(),但不显示getName(),即使两者具有相同的类型限定符。有人可以向我解释一下,为什么这个警告似乎只显示string 而不是int?我想这与 int 是一种原始数据类型有关 - 但究竟是什么?

【问题讨论】:

  • 基本上,在int RValue 上没有可能受其常量影响的操作。它首先是一个 RValue 意味着它。一般来说,类类型并非如此。

标签: c++ c++11 constants compiler-warnings qualifiers


【解决方案1】:

考虑以下几点:

struct MyType {
  void foo() const;
  void bar();
};

MyType getMutable();
const MyType getConst();

int main() {
  getMutable().foo(); // fine
  getMutable().bar(); // fine
  getConst().foo(); // fine
  getConst().bar(); // Not allowed!
}

int 没有任何等价物。您可以对int RValue 执行的一组操作与const int RValue 完全相同。这就是您收到冗余警告的原因。

【讨论】:

    【解决方案2】:

    [expr.type]:

    如果纯右值最初的类型为“cv T”,其中 T 是 cv 不合格的非类、非数组类型,则表达式的类型会在任何进一步分析之前调整为 T。

    本质是:你可以有const类或数组类型的表达式,但不能有const原始类型的表达式。

    【讨论】:

      【解决方案3】:

      std::string 是一个具有可以是常量的成员函数的类。如果你有一个类的常量对象,你可以只应用常量成员函数。

      对于基本类型,例如int,那么限定符 const 对返回值没有意义,因为在任何情况下您都无法更改返回值。

      这是一个演示程序

      #include <iostream>
      #include <string>
      
      template <typename T>
      const T f( const T &t )
      {
          return t;
      }
      
      int main() 
      {
          std::cout << f( std::string( "Hello World!" ) ).length() <<  '\n';
      
      //  Invalid assignment  
      //  f( 10 ) = 20;
          
          return 0;
      }
      

      程序输出是

      12
      

      如您所见,您可以将常量成员函数应用于std::string 类型的返回对象(但您不能应用非常量成员函数)。并且不能更改int类型的返回值。

      【讨论】:

      • 感谢您的解释和示例,我想我现在明白了:)
      【解决方案4】:

      由于int 不是一个类,返回类型为rvalue 就足以防止对返回对象的任何和所有修改。因此,

      getInt(20) = 500;
      

      不会是可编译的代码,并且没有可以在 int 类型的对象上调用的成员。这就是为什么 const 限定内置类型作为返回值没有意义,编译器会警告你。

      但不同班级的情况不同。

      getString("string").clear();
      

      根据 getString 是返回非 const 还是 const std::string 对象,可能是有效或无效代码,因此编译器不会在后一种情况下发出警告。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-11-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-26
        • 2014-02-15
        • 2014-09-09
        相关资源
        最近更新 更多