为什么默认参数以后不能在模板函数中添加? [英] Why default argument can't be added later in template functions?

查看:161
本文介绍了为什么默认参数以后不能在模板函数中添加?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C ++标准部分8.3.6.4说,

C++ standard section 8.3.6.4 says that


对于非模板函数,可以在稍后添加默认参数
在同一范围内的函数的声明。 [...]

For non-template functions, default arguments can be added in later declarations of a function in the same scope. [...]

但我的问题是,为什么不允许模板函数?不允许在模板函数的相同范围内的后面的声明中添加默认参数的理由是什么?

But my question is that why it isn't allowed for template functions? What is the rationale for not allowing addition of default arguments in later declarations in same scope for template functions?

考虑这个编译良好的程序。 (非模板功能)(请参阅直播演示此处

Consider this program which compiles fine. (non template function) (see live demo here.)

#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;
}

但是编译失败。 (模板功能)(请参阅直播示范此处

But following fails in compilation. (template function) (see live demo here.)

#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';
} 


推荐答案

在标准化过程中很早就添加了它(在C ++ 98中,但在ARM中不是这样)。

This is a historical limitation that was added fairly early in the standardization process (it was there in C++98, but not in the ARM).

我不记得确切的原因我的同事,谁的决定几乎肯定在那里)。但是,我有一个猜测...

I don't recall the exact reason (and neither does my colleague, who was almost certainly there when the decision was made). However, I have a guess...

然后,一个一个编译器通过解析通过重放令牌来实例化模板。一些几乎没有解析模板。考虑:

Back then, all-but-one compilers instantiated templates by replaying tokens through the parse. Some barely parsed templates at all. Consider:

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)

在解析调用(3)时,旧编译器通常只能访问实例化声明(1),而(2)仍然没有真正解析(只是令牌缓冲)。因此,这样的编译器不知道(3)中添加的默认参数。

When resolving call (3), older compilers therefore often only had access to the instantiated declaration (1), while (2) was still not really parsed (just token-buffered). As a result, such compilers were unaware of the added default argument in (3).

因此,委员会决定更通常地禁止在模板中添加默认参数。

Is suspect caution made the committee therefore decide to more generally disallow added default arguments in templates.

这种限制现在可能较少(技术上)合理,因为其他标准需求导致需要解析其通用形式的模板(虽然,例如MSVC仍然不这样做AFAICT)。也就是说,它可能仍然有点难以实现,因为默认参数现在可能必须在各种不同的上下文中实例化。

That limitation is probably less (technically) justified today, since other standard requirements have since resulted in the need to parse templates in their generic form (though, e.g., MSVC still doesn't do so AFAICT). That said, it might still be a bit of a pain to implement, because default arguments would now potentially have to be instantiated in various different contexts.

这篇关于为什么默认参数以后不能在模板函数中添加?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆