模板参数推导失败,函数参数/参数不匹配
Template Argument Deduction Failure and Function Parameters/Arguments Mismatch
考虑以下程序:
template <class T> struct A { using X = typename T::X; };
template <class T, typename A<T>::X* = nullptr> void f(T, int);
void f(...);
template <class T> void g(T, int, typename A<T>::X* = nullptr); // #
void g(...);
int main() {
// f(0, nullptr); // error
g(0, nullptr); // ok
}
g(0, nullptr)
编译而f(0, nullptr)
不编译(在Godbolt上的GCC主干和Clang主干下测试(。似乎在#
的模板参数推导过程中,编译器发现参数nullptr
与参数int
不匹配时,并没有实例化A<int>
。标准在哪里规定了这种行为?
这是CWG1391:
如果所有包含参与模板参数推导的模板参数,并且所有模板参数都是显式指定、推导或从默认模板参数中获取,其余参数为然后与相应的自变量进行比较。对于剩余的每个参数
P
的类型在替换之前是非依赖的任何显式指定的模板参数,如果参数A
不能隐式转换为P
,推导失败。
您可能被DR#1844咬伤。在[临时扣除]/8中,它表示:
如果替换导致类型或表达式无效,则类型推导失败。如果使用替换的参数编写,则无效类型或表达式是格式错误的类型或表达式,需要诊断。[注意:如果不需要诊断,则程序仍然不正确。访问检查是作为替换过程的一部分进行的--end note]只有函数类型、其模板参数类型和显式说明符的直接上下文中的无效类型和表达式才会导致推导失败。[注意:对类型和表达式的替换可能会导致类模板专门化和/或函数模板专门化的实例化、隐式定义函数的生成等效果。这些效果不在"直接上下文"中,可能会导致程序格式错误--尾注]
这里的问题是"即时上下文"没有真正给出定义,导致编译器之间存在差异。
相关文章:
- 将可变参数函数的参数封装在类实例中
- QML 使用带有参数C++函数
- 使用可变参数函数作为模板参数
- 如何在C++中伪造虚拟可变参数函数模板?
- 为什么可变参数函数不适用于模板
- C++ std::functional 中的可变参数函数模板
- 可变参数函数指针的定义对于VxWorks spyLib来说不清楚
- 使用可变参数函数覆盖具有不同函数签名的虚函数
- 考虑引用和常量的可变参数函数包装器
- 使用可变参数函数将整数和/或整数数组放入单个 int 数组中
- 在可变参数函数中转发特定范围的参数
- 通过引用传递参数;函数返回类型是否必须为 VOID?
- 使用带有一个参数函数的递归找到数字的平方
- 可变参数函数模板不能很好地使用 std::function 作为参数
- 多个可变参数函数的单个模板参数包?
- 参数数据类型未知的可变参数函数
- 可变参数函数参数包扩展
- 使用模板可变参数函数将多个参数传递给另一个函数
- 对可变参数函数的递归调用的链接器错误
- 通过像printf这样的可变参数函数传递一个带有常量字符*转换函数的类