Des*_*tor 15 c++ templates language-lawyer function-templates default-arguments
C++标准第8.3.6.4节说明了这一点
对于非模板函数,可以在稍后的同一范围内的函数声明中添加默认参数.[...]
但我的问题是,为什么它不允许模板功能?不允许在模板函数的同一范围内的后续声明中添加默认参数的基本原理是什么?
考虑这个编译好的程序.(非模板功能)(请参阅此处的现场演示.)
#include <iostream>
int f(int a,int b,int c=3);
int f(int a,int b=9,int c); // default argument in middle, ok allowed
int main()
{
f(3);
f(3,6);
f(3,6,9);
return 0;
}
int f(int a,int b,int c)
{
std::cout<<a<<' '<<b<<' '<<c<<'\n';
return 0;
}
Run Code Online (Sandbox Code Playgroud)
#include <iostream>
template <typename T>
void f(T a,int b,int c=3);
template <typename T>
void f(T a,int b=9,int c); // compiler error why???
int main()
{
f(3);
f(3,6);
f(3,6,9);
return 0;
}
template <typename T>
void f(T a,int b,int c)
{
std::cout<<a<<' '<<b<<' '<<c<<'\n';
}
Run Code Online (Sandbox Code Playgroud)
Dav*_* V. 11
这是在标准化过程中很早就添加的历史限制(它存在于C++ 98中,但不存在于ARM中).
我不记得确切的原因(我的同事也没有,在作出决定时几乎肯定在那里).不过,我猜...
那时,所有一个编译器通过解析重放令牌来实例化模板.一些几乎没有解析过的模板.考虑:
template<class T> struct S {
T f(T); // (1)
};
template<class T> T S<T>::f(T p = 42) { return p; } // (2)
S<int> s; // Causes the "real" parsing of (1), but not (2).
int r = s.f(); // (3)
Run Code Online (Sandbox Code Playgroud)
在解析call(3)时,较旧的编译器通常只能访问实例化的声明(1),而(2)仍然没有真正解析(只是令牌缓冲).结果,这些编译器不知道(3)中添加的默认参数.
怀疑是否因此委员会决定更普遍地禁止在模板中添加默认参数.
这种限制在今天可能较少(技术上)合理,因为其他标准要求因此导致需要以其通用形式解析模板(但是,例如,MSVC仍然没有这样做AFAICT).也就是说,实现它可能仍然有点痛苦,因为默认参数现在可能必须在各种不同的上下文中实例化.
| 归档时间: |
|
| 查看次数: |
884 次 |
| 最近记录: |