当使用nullptr_t时,为什么会出现“参数设置但未使用”的警告?

11

我有一个自定义类实现了operator==nullptr

以下是我简化为一个简单示例的代码:

#include <cstdint>
#include <iostream>

class C {
private:
    void *v = nullptr;

public:
    explicit C(void *ptr) : v(ptr) { }

    bool operator==(std::nullptr_t n) const {
        return this->v == n;
    }
};

int main()
{
    uint32_t x = 0;
    C c(&x);
    std::cout << (c == nullptr ? "yes" : "no") << std::endl;

    C c2(nullptr);
    std::cout << (c2 == nullptr ? "yes" : "no") << std::endl;


    return 0;
}
代码按预期工作,但是g++(版本6.2.1)给我以下警告:
[Timur@Timur-Zenbook misc]$ g++ aaa.cpp -o aaa -Wall -Wextra
aaa.cpp: In member function ‘bool C::operator==(std::nullptr_t) const’:
aaa.cpp:12:36: warning: parameter ‘n’ set but not used [-Wunused-but-set-parameter]
     bool operator==(std::nullptr_t n) const {
                                    ^

我做错了什么?

注意:我正在使用-Wall -Wextra


3
请尝试使用"-Wall -Wextra"命令。在wandbox的6.1版本上可以重现该问题:http://melpon.org/wandbox/permlink/OGeniUkFzE8dRP1v - krzaq
1
有趣。请注意,您甚至可以将其简化:#include <iostream> int main() { std::nullptr_t n = nullptr; if (n == nullptr) std::cout << "yes"; } - Christian Hackl
1
@wasthishelpful: 或许GCC在这里生成警告是正确的,但是“参数设置但未使用”这个措辞确实令人不满意。 - Christian Hackl
1
在函数中添加n=n;可以消除警告。看起来编译器知道n可能为NULL,并简单地优化了对它的引用,最终产生了警告。 - Sam Varshavchik
2
nullptr_t 对象进行 lvalue-to-rvalue 转换不会访问其存储的值。但还是应该提交一个 bug 报告。 - T.C.
显示剩余3条评论
1个回答

9

虽然这并不是为什么会发生这种情况的答案,但是无论如何,n可能具有什么值呢?

返回this->v == nullptr并使参数未命名可以消除警告:

bool operator==(std::nullptr_t) const {
    return this->v == nullptr;
}

编辑:

声明 n 为 rvalue 引用,或者作为 const lvalue 引用也会消除警告:

bool operator==(std::nullptr_t&& n) const {
    return this->v == n;
}

bool operator==(const std::nullptr_t& n) const {
    return this->v == n;
}

编辑2:

有关如何消除未使用变量警告的更多方法,请参见此问题(感谢@ShafikYaghmour在评论中指出)。上述示例涵盖了“隐式”方法。

也可以采用显式解决方案,但我认为这些方案看起来不太连贯,因为实际上已经使用了该参数。测试过的显式解决方案包括:

bool operator==(std::nullptr_t n) const {
    (void)n;
    return this->v == n;
}

#define UNUSED(expr) do { (void)(expr); } while (0)

bool operator==(std::nullptr_t n) const {
    UNUSED(n);
    return this->v == n;
}

针对GCC的非便携式解决方案:

bool operator==(__attribute__((unused)) std::nullptr_t n) const {
    return this->v == n;
}

3
如果这不是一个回答的话,那么我认为它应该是一条评论。 - Christian Hackl
7
我认为这实际上是一个答案,因为它提供了一种非常合理的方法来避免警告。对于类型为 std::nullptr_t 的对象使用标识符是相当无意义的。 - Angew is no longer proud of SO
1
我同意,这是一个有效的答案。 - Sam Varshavchik
3
然而,这种情况可能会出现在一个模板中,其中std::nullptr_t实际上是一个类型参数。 - Christian Hackl
@Venemo 我认为这是不可能的。你有一个可行的例子吗? - rocambille
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接