为什么这个函数指针的可变模板参数推导失败
Why does the variadic template argument deduction fail for this function pointer?
在下面的最小示例中,S::foo
工作,但S::bar
失败。
唯一的区别是参数包Ts
和Us
的顺序。
struct FPtr
和S::lol
是我找到的最好的变通方法,但在实践中使用起来相当不舒服。
为什么bar
的参数推导失败(尤其是因为我已经明确指定了类型,所以根本不应该进行推导)?这是编译器错误(出现在clang++ 3.5
和g++ 4.9
中),还是出于某种原因在标准中?
template<typename ... Ts>
struct FPtr {
FPtr(void (*val)(Ts ...)) : val{val} {}
void (*val)(Ts ...);
};
template<typename ... Ts>
struct S {
template<typename ... Us>
void lol(FPtr<Us ..., Ts ...>) {}
template<typename ... Us>
void foo(void (*)(Ts ..., Us ...)) {}
template<typename ... Us>
void bar(void (*)(Us ..., Ts ...)) {}
};
void f(int, float) {}
void g(float, int) {}
int main() {
S<int> s;
s.lol<float>(FPtr<float, int>(g));
s.foo<float>(f);
s.bar<float>(g);
}
错误消息为:
$ clang++ -std=c++14 t27.cpp -Wall -Wextra -pedantic
t27.cpp:31:4: error: no matching member function for call to 'bar'
s.bar<float>(g);
~~^~~~~~~~~~
t27.cpp:18:7: note: candidate template ignored: failed template argument deduction
void bar(void (*)(Us ..., Ts ...)) {}
^
注意:我已经在GCC和LLVM错误跟踪器上报告了这个错误。
我已经用Clang和GCC测试了这段代码,但它们都无法编译程序。我认为这是两个编译器中的一个错误。出现在参数列表末尾之前的函数参数包是非推导上下文。在替换明确指定的模板参数后,它应该构建函数
template<>
S<int>::bar(void (*)(float, int));
其应当与呼叫相匹配。Clang和GCC以前在这样的领域遇到过问题,众所周知,他们的诊断没有多大帮助。然而,令人惊讶的是,VC++编译了代码。
考虑以下两种编译器都可以使用的内容。
template<class... Ts>
struct S {
template<class... Us>
void bar(Us..., Ts...);
};
int main() {
S<int>().bar<int>(1, 2);
}
您的程序具有相同的语义,应该一视同仁。
相关文章:
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- 视图中的参数推导失败:take_while
- variadic模板中的模板参数推导失败
- 当给定默认值时,为什么此模板参数推导失败
- 模板参数推导失败,函数参数/参数不匹配
- 为什么模板参数推导失败?
- 嵌套参数包扩展失败
- 模板参数的 C++ 自动模板推导失败
- 调试模板时出现问题.专门针对 Linux GCC 7、GCC 6、GCC 5、GCC 4.9 错误构建失败:模板参数 1
- 使用显式模板参数列表和 [temp.arg.explicit]/3 的函数调用的演绎失败
- 失败,出现错误 87:参数不正确.如何判断哪个参数不正确?
- 在 g++ 6.2.1 中将参数包转发到 constructor() 失败
- 当变量和参数名称匹配时,移动语义构造失败
- 作为模板参数的成员函数指针在继承的成员函数上失败,如何以及为什么?
- 模板参数推导/替换失败,lambda作为函数指针
- 为什么在 std::transform 中使用函数对象参数失败并且需要 lambda 表达式
- C++模板参数失败,不是从错误派生的
- CreateThread参数失败
- 在CreateProcess中传递命令行参数失败