在函数调用中,为什么nullptr不匹配指向模板对象的指针?

 俊铭心怡雅琪 发布于 2023-02-12 16:42

以下是一个完美运行的代码示例:


#include
#include

template< class D, template< class D, class A > class C, class A = std::allocator< D > >
void foo( C< D, A > *bar, C< D, A > *bas ) {
  std::cout << "Ok!" << std::endl;
}

int main( ) {
  std::vector< int > *sample1 = nullptr;
  std::vector< int > *sample2 = nullptr;
  foo( sample1, sample2 );
  return( 0 );
}

但是,在下面的代码中,编译器无法将std :: vector *与nullptr匹配为第二个参数,甚至能够从第一个参数中扣除模板类型.


#include
#include

template< class D, template< class D, class A > class C, class A = std::allocator< D > >
void foo( C< D, A > *bar, C< D, A > *bas ) {
  std::cout << "Ok!" << std::endl;
}

int main( ) {
  std::vector< int > *sample = nullptr;
  foo( sample, nullptr );
  return( 0 );
}

错误消息是:


$ g++ -std=c++11 nullptr.cpp -o nullptr

nullptr.cpp: In function ‘int main()’:

nullptr.cpp:11:24: error: no matching function for call to ‘foo(std::vector*&, std::nullptr_t)’

   foo( sample, nullptr );

nullptr.cpp:11:24: note: candidate is:

nullptr.cpp:5:6: note: template class C, class A> void foo(C*, C*)

 void foo( C< D, A > *bar, C< D, A > *bas ) {

nullptr.cpp:5:6: note:   template argument deduction/substitution failed:

nullptr.cpp:11:24: note:   mismatched types ‘C*’ and ‘std::nullptr_t’

   foo( sample, nullptr );

为什么会这样?

2 个回答
  • 这就是模板推理的工作方式:不进行转换.

    这个问题也不是特有的nullptr,考虑到极其简单的情况:

    #include <iostream>
    
    struct Thing {
        operator int() const { return 0; }
    } thingy;
    
    template <typename T>
    void print(T l, T r) { std::cout << l << " " << r << "\n"; }
    
    int main() {
        int i = 0;
        print(i, thingy);
        return 0;
    }
    

    其中收益率:

    prog.cpp: In function ‘int main()’:
    prog.cpp:12:17: error: no matching function for call to ‘print(int&, Thing&)’
      print(i, thingy);
                     ^
    prog.cpp:12:17: note: candidate is:
    prog.cpp:8:6: note: template<class T> void print(T, T)
     void print(T l, T r) { std::cout << l << " " << r << "\n"; }
          ^
    prog.cpp:8:6: note:   template argument deduction/substitution failed:
    prog.cpp:12:17: note:   deduced conflicting types for parameter ‘T’ (‘int’ and ‘Thing’)
      print(i, thingy);
                     ^
    

    因此,转换nullptrint*不发生向模板参数推导任一.如上所述,您有两种解决问题的方法:

    指定模板参数(因此不会发生扣减)

    自己转换参数(扣除发生,但在显式转换后)

    2023-02-12 16:45 回答
  • 从C++标准(4.10指针转换[conv.ptr])

    1空指针常量是整数类型的整数常量表达式(5.19)prvalue,其计算结果为零或类型为std :: nullptr_t的prvalue.空指针常量可以转换为指针类型; 结果是该类型的空指针值,并且可以与对象指针或函数指针类型的每个其他值区分开.这种转换称为空指针转换.

    在您的第一个例子中,您的两个nullptr已经在模板参数推断之前被转换.所以没有问题,你有两次相同的类型.

    在第二个中,有一个std::vector<int>和一个std::nullptr_t不匹配.你必须自己做转换:static_cast<std::vector<int>*>(nullptr).

    2023-02-12 16:46 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有