gpt4 book ai didi

c++ - 非常量指针类型的参数不调用带有常量指针模板类型参数的函数

转载 作者:行者123 更新时间:2023-12-02 10:07:36 29 4
gpt4 key购买 nike

根据我的理解,const指针函数参数应该能够接受const和非const指针。在后一种情况下,通过指针修改值是非法的。

假设我具有以下模板功能

template <typename T1, typename T2>
decltype(auto) plus(T1 a, T2 b) {
return a + b;
}

template <typename T1, typename T2>
decltype(auto) plus(const T1* a, const T2* b) {
return *a + *b;
}

int main() {

int a {2}, b {3};
std::cout << plus(a, b) << std::endl;

int *first { new int {2} }, *second { new int {3} };

// it seems here that the return type is deduced to be void*?

std::cout << plus(first, second) << std::endl;
}

第二个函数调用正确调用了 plus模板函数,该模板函数接受指针参数,但将返回类型推导为 void*
但是,如果我将模板签名更改为
template <typename T1, typename T2>
decltype(auto) plus(T1* a, T2* b) {
return *a + *b;
}

这将产生正确的结果。

这里发生了什么?

最佳答案

plus(first, second)调用第一个模板重载,因为它是更好的匹配。

推导模板参数后(拳头使用T1 == T2 == int*,第二步使用T1 == T2 == int),这两种重载都是可行的。但是,对于这两个参数中的每个参数,第一个重载仅需要从左值到右值的转换,而第二个重载则需要从左值到右值的转换,然后是限定符转换(添加const)。

因此,这两个参数的隐式转换顺序对于第一次过载来说更好,因此可以通过过载解析来选择。甚至不考虑功能模板的部分排序。

但是,用T1 == T2 == int*调用第一个功能模板的格式不正确,因为如果a + ba都是指针类型,则不允许b。您的编译器应该已经在这里给您一个错误。

使用第二个模板重载的替代签名,将不需要上面提到的其他限定转换,并且两个重载的参数的隐式转换顺序将相同。

因此,将考虑使用功能模板的部分排序来决定选择哪个重载,并且由于第二个模板比第一个模板更专业,因此将选择第二个。

使用T1 == T2 == int后,它将按预期工作,因为*a + *b添加了两个int而不是两个指针,从而产生了int的返回类型,因为*a + *b是一个prvalue。

关于c++ - 非常量指针类型的参数不调用带有常量指针模板类型参数的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59419212/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com