C++ 默认函数参数值在模板中可见,但不应为';t(gcc)
考虑以下代码:C++ 默认函数参数值在模板中可见,但不应为';t(gcc),c++,g++,language-lawyer,C++,G++,Language Lawyer,考虑以下代码: #include <utility> void f(int, int); void g(int, int); struct functor { template<typename... T> void operator()(T&&... params) { return f(std::forward<T>(params)...); } }; int main() {
#include <utility>
void f(int, int);
void g(int, int);
struct functor
{
template<typename... T>
void operator()(T&&... params)
{
return f(std::forward<T>(params)...);
}
};
int main()
{
functor()(1); // can use the default value here, why?!
// g(1); // error here as expected, too few arguments
}
void f(int a, int b = 42) {}
void g(int a, int b = 24) {}
#包括
无效f(int,int);
无效g(int,int);
结构函子
{
模板
void运算符()(T&…参数)
{
返回f(标准::转发(参数)…);
}
};
int main()
{
函子()(1);//可以在这里使用默认值,为什么?!
//g(1);//此处出现预期错误,参数太少
}
void f(inta,intb=42){
void g(inta,intb=24){}
这是一个围绕函数调用的薄包装。但是,在functor::operator()
中,f
没有第二个参数的默认值(在定义中,它仅在main
之后可见),因此代码不应编译。虽然g++5.2成功地编译了它,但clang++给出了正确执行两阶段名称查找的编译器所期望的消息:
错误:对函数“f”的调用在
模板定义未通过参数相关查找找到
返回f(标准::转发(参数)…)
这是一个gcc错误还是我遗漏了什么?也就是说,在main()
下定义f
之后是实例化点吗?但即使在这种情况下,它也不应该工作,因为在第二阶段,功能只能通过ADL找到,而这里不是这样。:
对于后缀表达式为从属名称的函数调用,使用常用的查找规则([basic.lookup.unqual],[basic.lookup.argdep])查找候选函数,但以下情况除外:
- 对于使用非限定名称查找([basic.lookup.unqual])的查找部分,只能找到模板定义上下文中的函数声明
- 对于使用关联名称空间([basic.lookup.argdep])的查找部分,只能找到在模板定义上下文或模板实例化上下文中找到的函数声明
请注意,ADL在这里甚至不起作用,因为所涉及的类型是基本类型(它们关联的名称空间集是空的)。翻译单元的末尾也是一个有效的实例化点。是的,但它仍然不应该起作用,因为在第二阶段,只执行ADL。如果在文件末尾实例化,带有默认参数的
f
的定义可见。。。不知道程序是否格式不正确…@Jarod42 Ohh我明白了,是的,我认为你是对的,因为f
本身以前就被发现了,现在带有默认参数的定义是可见的。定义不是其他函数,它只是同一个函数。