c++ - 有没有解决 nullptr_t 和指针重载之间歧义的好方法?

标签 c++ c++14

当使用文字 0 时在 C++ 中,编译器无法区分指针和 nullptr_t函数的重载。
说明问题的代码:

struct Bar {};

void foo(Bar*) {
  std::cout << "Bar*" << std::endl;
}

void foo(std::nullptr_t) {
  std::cout << "nullptr_t" << std::endl;
}

TEST(NullPtrTest, ambiguity) {
  foo(nullptr);  // OK
  foo(0);  // ERROR
}
使用 Visual Studio 2019:
error C2668: '`anonymous-namespace'::foo': ambiguous call to overloaded function
message : could be 'void `anonymous-namespace'::foo(std::nullptr_t)'
message : or       'void `anonymous-namespace'::foo(`anonymous-namespace'::Bar *)'
message : while trying to match the argument list '(int)'
使用 GCC 9:
Test.cpp: In member function ‘virtual void {anonymous}::NullPtrTest_ambiguity_Test::TestBody()’:
Test.cpp:425:8: error: call of overloaded ‘foo(int)’ is ambiguous
  425 |   foo(0);  // ERROR
      |        ^
Test.cpp:415:6: note: candidate: ‘void {anonymous}::foo({anonymous}::Bar*)’
  415 | void foo(Bar*) {
      |      ^~~
Test.cpp:419:6: note: candidate: ‘void {anonymous}::foo(std::nullptr_t)’
  419 | void foo(std::nullptr_t) {
      |      ^~~
有什么好的方法来解决这个问题?
我不想做的事情:
  • 替换 0带有 nullptr 的文字到处。我们的遗留代码库中的实例太多了。
  • 添加 intlong (或类似的)过载。由于0将是唯一有效的整数值,您必须添加运行时检查,这会很丑陋。
  • 删除 nullptr_t重载并在运行时检查指针重载中的值。这行得通,并不可怕,但它阻止了我们对空常量进行优化的实现。

  • 谢谢!
    说明:
  • 我们正在使用 C++14。但是,这些函数被 C++11 之前的许多代码使用。
  • 特定用例是提供优化的 constexpr nullptr 时执行或 0用来。一般的指针实现仍然需要检查空值。 nullptr_t重载并不是真正必要的,但它会很好。
  • 我主要是问这个问题,看看是否有一些我没有考虑的选项。
  • 最佳答案

    模板不在排除列表中 - 使其成为模板,仅限于接受 Bar* :

    #include <iostream>
    #include <type_traits>
    
    struct Bar {}; 
    
    template <typename T>
    typename std::enable_if<std::is_same_v<T, Bar>>::type foo(T*) {
      std::cout << "Bar*\n";
    }   
    
    void foo(std::nullptr_t) {
      std::cout << "nullptr_t\n";
    }   
    
    int main() {
      Bar b;
      foo(nullptr);
      foo(0);
      foo(&b);
    }
    
    我想在实践中你的Bar*可能会传递派生类型,即,您可能需要 std::enable_if 中的不同条件.如果 foo(Bar*)有点实质性,您可能不想在 header 中实现。但是,由于无论如何只有一个实例,您可以将实现放入 .cpp文件并显式实例化它,或者,分派(dispatch)给一个实现函数。

    关于c++ - 有没有解决 nullptr_t 和指针重载之间歧义的好方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65419576/

    相关文章:

    c++ - 为什么我需要同时包含 iostream 和 fstream header 才能打开文件

    c++ 二维数组类的动态分配

    c++ - ios_base 和静态成员

    c++ - qtcreator中C++14的编译

    c++ - 方法头部的模板化模板参数名称无效

    C++:静态分析工具,将警告丢失的 header

    C++ - Unresolved external 错误

    c++ - 为什么在函数中使用多个 getlines 来输入字符串会出现意外行为?

    c++ - 我不明白在 C++14 的 [namespace.memdef]/3 中的示例中,模板函数如何成为类 A::X::Y 的友元

    c++ - 在现代 C++ 中,是否仍应使用 volatile 与 ISR 共享数据?