为什么不能为显式模板特化指定默认参数?

Tho*_*son 24 c++ templates

下面的代码无法通过编译,这个编译器错误的考虑是什么?

template<class T> void f(T t) {};

template<> void f<char>(char c = 'a') {}
Run Code Online (Sandbox Code Playgroud)

错误消息:在函数模板的显式特化上不允许使用默认参数

vit*_*aut 25

我认为这个错误背后的基本原理是由于函数模板中的默认参数也适用于它的特化,并且不允许在C++中多次定义默认参数.

考虑以下:

#include <iostream>

template<class T> void f(T t = 'a') {}

template<> void f<char>(char c)
{
    std::cout << c << std::endl;
}

int main(int argc, char **argv)
{
    f<char>();
}
Run Code Online (Sandbox Code Playgroud)

这将打印a意味着使用主模板中定义的默认参数调用特化.

如果每个专业化需要不同的默认参数,可以使用下面说明的方法:

#include <iostream>

template<class T>
struct default_arg
{
    static T get() { return T(); }
};

template<class T> void f(T t = default_arg<T>::get()) {}

template<>
struct default_arg<char>
{
    static char get() { return 'a'; }
};

template<> void f<char>(char c)
{
    std::cout << c << std::endl;
}

int main(int argc, char **argv)
{
    f<char>();
}
Run Code Online (Sandbox Code Playgroud)


Che*_*Alf 15

C++98§12.7/ 21"默认函数参数不应在......函数模板的显式特化中指定".

关于基本原理,我认为它与总是针对主模板解决的调用有关.在不更改查找规则的情况下,无法解析主要模板所需的参数.

  • 事实上,通过名称查找无法找到显式的专业化。模板实参推导是在函数模板上完成的,如果仅由`f()`调用,则无法推导`T`。应该如何选择“char”。有人可能会说可以执行“f&lt;char&gt;()”,并且如果存在提供默认参数的“f&lt;char&gt;”显式特化,则将使用它。但我认为这没什么用,它只会使模板参数推导进一步复杂化。 (2认同)