gpt4 book ai didi

c++ - 函数模板特化失败?

转载 作者:可可西里 更新时间:2023-11-01 18:37:12 24 4
gpt4 key购买 nike

#include <iostream>

template <class T>
void foo(T) {
std::cout << "foo(T)" << std::endl;
}

template <class T>
void foo(T*) { //#3
std::cout << "foo(T*)" << std::endl;
}

#define TEST

#ifdef TEST
template <>
void foo(int*) { //#1
std::cout << "foo(int*)" << std::endl;
}
#else
template <>
void foo<int*>(int*) { //#2
std::cout << "foo<int*>(int*)" << std::endl;
}
#endif

int main(int argc, char **argv) {
int* p = 0;
foo(p);
return 0;
}

上面的#1#2有什么区别?如果我定义 TEST,则 #1 有效,但如果我将其注释掉,则 #3 有效。在这里编写函数模板特化的正确方法是什么?

最佳答案

#1 声明了#3 的函数模板特化并自动推导模板参数。 #2 是您为 T=int* 定义的第一个模板(没有编号的模板,我们称它为#0)的特化。它不能是 #3 的特化,因为用指定的 int* 替换 T 会导致 int** 参数。

当您调用 foo 时,重载解析现在首先选择最合适的基本模板,然后检查该模板是否存在任何现有的特化。定义了 TEST 后,有两个基本模板(#0 和 #3),#3 更匹配并被选中。然后编译器检查该模板的特化,#1 更适合并被调用。

没有定义 TEST,仍然有两个基本模板(#0 和 #3),#3 是一个更好的匹配并被选中。然后编译器检查该模板的特化,但由于 #2 特化了 #0 而不是 #3,它不被考虑并且 #3 被调用结束。

这是Why not Specialize Function Templates的经典例子.那里对问题进行了更详细的解释。

简单的解决方案是根本不特化函数模板,而只是为特殊类型添加新的重载:

// no template, just a normal function
void foo(int*) {
std::cout << "foo(int*)" << std::endl;
}

关于c++ - 函数模板特化失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8952715/

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