Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 默认函数参数值在模板中可见,但不应为';t(gcc)_C++_G++_Language Lawyer - Fatal编程技术网

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
本身以前就被发现了,现在带有默认参数的定义是可见的。定义不是其他函数,它只是同一个函数。