85

当我第一次使用 GCC 4.3 编译我的 C++ 代码时(在使用选项成功编译它并且在 4.1、4.0、3.4 上没有警告之后-Wall -Wextra)我突然收到了一堆形式的错误warning: type qualifiers ignored on function return type

考虑temp.cpp

class Something
{
public:
    const int getConstThing() const {
        return _cMyInt;
    }
    const int getNonconstThing() const {
        return _myInt;
    }

    const int& getConstReference() const {
        return _myInt;
    }
    int& getNonconstReference() {
        return _myInt;
    }

    void setInt(const int newValue) {
        _myInt = newValue;
    }

    Something() : _cMyInt( 3 ) {
        _myInt = 2;
    }
private:
    const int _cMyInt;
    int _myInt;
};

运行g++ temp.cpp -Wextra -c -o blah.o

temp.cpp:4: warning: type qualifiers ignored on function return type
temp.cpp:7: warning: type qualifiers ignored on function return type

有人可以告诉我我做错了什么违反了 C++ 标准吗?我想当按值返回时,前导const是多余的,但我无法理解为什么需要用它生成警告。还有其他地方我应该放弃 const 吗?

4

8 回答 8

110

它不违反标准。这就是为什么它们是警告而不是错误的原因。

事实上,你是对的——领先const是多余的。编译器会警告您,因为您添加了在其他情况下可能有意义的代码,但在这种情况下没有任何意义,并且它希望确保您稍后在返回值最终变成可修改时不会感到失望。

于 2009-07-15T21:43:32.617 回答
20

我在编译一些使用 Boost.ProgramOptions 的代码时遇到了这个警告。我使用-Werror了所以警告正在杀死我的构建,但是由于警告的来源在 Boost 的深处,我无法通过修改我的代码来摆脱它。

经过大量挖掘,我找到了禁用警告的编译器选项:

-Wno-ignored-qualifiers

希望这可以帮助。

于 2009-08-19T09:34:54.867 回答
7

仅当您返回引用或指针(在这种情况下是指向常量的指针而不是常量指针)时,返回常量值才有意义,因为调用者能够修改引用(指向)的值。

对与您的问题无关的代码的另一条评论:我认为最好使用 setter 而不是

int& getNonconstReference() {
    return _myInt;
}

应该是:

void setMyInt(int n) {
  _myInt = n;
}

此外,返回对 int 的 const 引用是没有用的。对于复制或移动成本更高的更大对象来说,这确实有意义。

于 2015-05-19T14:59:01.800 回答
2

有了这个

struct Foo { Foo(int) {} operator bool() { return true; } };

然后

Foo some_calculation(int a, int b) { Foo result(a + b); /*...*/ return result; }

这个例子

if (some_calculation(3, 20) = 40) { /*...*/ }

编译没有警告。当然,这种情况很少见。但是 const 的正确性难道不是让人们很难做错事吗?并且期望人们尝试错误的事情,返回类型应该声明为 const。并且:g++ 警告忽略分类器,但不会忽略它。我认为,警告是关于获取副本并忽略其副本上的 const 分类器的用户。但这不应该是一个警告,因为这是绝对正确的行为。这样做是有道理的。

于 2010-07-13T11:32:25.853 回答
1

-pedantic 不应该只允许严格遵守 ISO 标准吗?取决于 -std= 当然...

于 2011-02-13T23:55:42.780 回答
1

在声明函数返回指向不应修改的对象的指针时,此警告也有助于避免混淆:

// "warning: type qualifiers ignored on function return type"
// as the pointer is copied. 
Foo* const bar();

// correct:
const Foo* bar();
于 2014-04-07T12:06:45.867 回答
0

在基本类型结果上存在差异const,它被忽略,而const在类类型结果上,它通常会造成严重破坏。

namespace i {
    auto f() -> int const { return 42; }
    void g( int&& ) {}
}

namespace s {
    struct S {};
    auto f() -> S const { return {}; }
    auto g( S&&  ) {}
}

auto main() -> int
{
    { using namespace i; g( f() ); }    // OK
    { using namespace s; g( f() ); }    // !The `const` prevents this.
}

这就是编译器在第一种情况下发出警告的原因:这是一种特殊情况,可能不会像人们天真地期望的那样。

const对于现代编程,恕我直言,对类类型结果的警告也会很好,因为它禁止移动语义;对于人们所设想的任何微小优势,都要付出相当高昂的代价。

于 2016-03-29T10:31:09.693 回答
-5

Scott Meyers指出,有人想要返回const值是有充分理由的。这是一个例子:

int some_calculation(int a, int b) { int res = 0; /* ... */ return res; }

/* Test if the result of the calculation equals 40.*/
if (some_calculation(3,20) = 40)
{

}

你看到我做错了什么吗?这段代码绝对正确,应该可以编译。问题是编译器不明白您打算比较而不是分配value 40

使用const返回值,上面的示例将无法编译。好吧,至少如果编译器不丢弃const关键字。

于 2010-04-20T12:16:12.807 回答