默认函数参数值在模板中可见,但不应 (gcc)
Default function parameter value visible in template but it shouldn't (gcc)
考虑以下代码:
#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) {}
这是一个函数调用的瘦包装。但是,在functor::operator()
中,f
没有第二个已知参数的默认值(在定义中,只有在main
之后才可见),因此代码不应该编译。g++5.2成功地编译了它,但clang++抛出了预期的消息,这是正确执行两阶段名称查找的编译器所期望的:
错误:对函数"f"的调用在依赖于参数的查找未找到模板定义返回f(std::forward(params)…);
这是一个gcc错误还是我遗漏了什么?也就是说,在f
的定义之后实例化的点在main()
之下吗?但即使在这种情况下,它也不应该起作用,因为在第二阶段,只能通过ADL找到功能,而这里的情况并非如此。
〔temp.dep.candidate〕:
对于后缀表达式是依赖名称的函数调用,使用常用查找规则([basic.lookup.uqual]、[basic.lookup.argdep])查找候选函数,但以下情况除外:
对于使用非限定名称查找的查找部分([basic.lookup.uqual]),只找到模板定义上下文中的函数声明。
对于使用关联命名空间的查找部分([basic.lookup.argdep]),只找到在模板定义上下文或模板实例化上下文中找到的函数声明。
如果调用格式不正确,或者如果在关联的命名空间中进行查找,会找到更好的匹配考虑了所有转换单元中那些名称空间中引入的具有外部链接的所有函数声明,而不仅仅是考虑模板定义和模板实例化中的声明上下文,则程序具有未定义的行为
注意,ADL在这里甚至不起作用,因为所涉及的类型是基本的(它们的一组关联名称空间是空的)。
相关文章:
- 类模板参数推导-clang和gcc不同
- 带有自动参数的函数使用 GCC 编译,但不使用 Visual C++ 编译
- GCC/CLang不同意模板模板参数的部分特化
- 调试模板时出现问题.专门针对 Linux GCC 7、GCC 6、GCC 5、GCC 4.9 错误构建失败:模板参数 1
- 使用具有默认参数的函数模板进行 decltype 会使结果混乱(一个有趣的问题或 gcc 的错误)
- constexpr 函数的常量引用参数:gcc/msvc vs clang/icc
- 隐蔽的 gcc 参数到 CMake 文件
- typedef名称与可变模板参数名称一致时出现GCC错误
- 将带有模板化方法的类作为带有GCC的模板参数传递
- 在if constexpr中使用带参数包的概念时,升级到gcc 9后出现编译错误
- 模板模板参数导致Clang下的编译器错误,而不是GCC
- GCC 仪器 - 是否可以自动输出函数的参数?
- 带有 gcc 和 clang 的可变参数宏扩展的奇怪行为
- 修改嵌套 lambda 中捕获的参数:gcc 与 clang?
- 使用函数参数作为常量表达式的一部分 - gcc vs clang
- 使用 GCC 5 进行模板参数阴影
- 类数据成员指针的非类型模板参数包无法使用 gcc 编译
- 在 mingw64-gcc 上可能存在可变参数的错误
- 在折叠表达式中扩展参数包作为 lambda 捕获的一部分 - gcc 与 clang
- GCC:指定的界限取决于源参数的长度