“专业化不参与超载”

"specializations don’t participate in overloading"

提问人:anurag86 提问时间:2/4/2020 最后编辑:anurag86 更新时间:2/4/2020 访问量:307

问:

“函数模板的专业化”的真正含义是什么 不要参与过载解决。仅考虑基本模板”

我用它的专用版本编写了一个简单的模板函数,可以看到它调用了specialized:

// Base template
template <typename T>
T max(T a, T b) {
    std::cout << "Base Template" << std::endl;
    return (a>b) ? a : b;
}

// Specialization for int
template<>
int max<int>(int a, int b) {
    std::cout << "int specialization" << std::endl;
    return (a>b) ? a : b;
}
max(2,3);// prints "int specialization"

查看与此概念相关的其他 StackOverflow,我发现了另一篇文章,其中证明专业化不参与重载,他展示了以下示例,其中没有调用专用版本,我仍然不确定为什么没有调用它。但除此之外,在此示例中,参数没有变量名称,但该部分仍然没有编译或运行时错误(char const* const&)

template<typename T>
void f(T const&)
{
        std::cout<<std::endl<<"Base Template for f() called\n";
}

template<>
void f<char const * const &>(char const* const&)
{
        std::cout<<std::endl<<"Specialized f() for char const* called\n";
}
f("Hello") //prints "Base Template for f() called"

总而言之,我仍在试图弄清楚“函数模板的专业化不要参与过载解决”的含义。只考虑基本模板“,如果有人可以用一个例子来解释(以及为什么在第二个例子中调用基本模板)。 其次,为什么程序在第二个示例中没有变量名的情况下编译并运行良好。

C++ 模板

评论

0赞 Some programmer dude 2/4/2020
模板专用化与重载不同。如果您有模板函数,则会重载。int max(int a, int b);
0赞 VLL 2/4/2020
你能链接另一个帖子吗?
0赞 anurag86 2/4/2020
是的,非模板化函数将优先于模板化专用版本。是这样吗?这是这句话的意思吗?
1赞 Bob__ 2/4/2020
如果您能抽出一些时间,观看 Walter E. Brown 关于函数模板的演讲可能会很有用。
0赞 anurag86 2/4/2020
@Bob__当然。谢谢

答:

5赞 Sneaky Turtle 2/4/2020 #1

如果尝试,即使 a 可转换为 .因此,专业化不参与过载解决。max(5, 7.0)doubleintintmax

template <typename T>
T max(T a, T b);

template <>
int max(int a, int b);

max(5, 7.0); // compiler error (no matching function)

但是,如果您使用常规函数而不是模板专用化,则将获得预期的行为。

template <typename T>
T max(T a, T b);

int max(int a, int b);

max(5, 7.0); // this is fine

当编译器考虑参数类型时,它会按以下顺序查找函数(ADL和其他细节比这更复杂):(int, double)

  • 完全匹配的函数(例如.所以现阶段不会考虑)max(int, double)max(int, int)
  • 匹配函数模板(例如.所以不会被考虑,因为不能同时是和max(T, U)max(T, T)Tintdouble)
  • 具有兼容参数的函数(例如 since 隐式转换为max(int, int)doubleint)

请注意,我没有提到函数模板专用化。如果找到匹配的函数模板,则将使用完全匹配的专用化(因此,如果您专门用于 s,但您调用了 s,则不会使用该专用化),否则将使用基本模板。doubleint

有关更好的解释,请参阅 cppreference

评论

0赞 anurag86 2/4/2020
同意。但是,混乱不止于此,这就是我提供第二个示例的原因。在这种情况下,将专用版本称为 不合适吗?您可以尝试使用specialized,您将始终看到specialized被调用。现在只需将 更改为,您将看到 Base 模板而不是 specialized 被调用。不知道为什么char const * const&template<typename T>max(T a)tempalte<>max(int a)intint&
0赞 anurag86 2/4/2020
另外,关于第二个问题 - 在没有变量名称的情况下,如何编译和运行它。
0赞 Sneaky Turtle 2/4/2020
如果您专注于并使用 an 进行呼叫,那么这与专业化不完全匹配(正如我在倒数第二段中所说),因此将使用基本模板。int &int
2赞 Sneaky Turtle 2/4/2020
哦,我明白你的困惑了。的类型不是 。是的。这与专业化不完全匹配,因此使用基本模板。"hello"const char *const char [6]
1赞 Sneaky Turtle 2/4/2020
如果不使用函数参数,则无需提及其名称。顺便说一句,要专业化,您可以使用,因此将选择专业化。ftemplate<> void f(char const (&)[6])f("hello")