Que*_*tin 12 c++ overloading sfinae template-argument-deduction c++17
我正在尝试bar在另一个函数的参数(foo1/ foo2)的上下文中解析重载函数()的地址.
struct Baz {};
int bar() { return 0; }
float bar(int) { return 0.0f; }
void bar(Baz *) {}
void foo1(void (&)(Baz *)) {}
template <class T, class D>
auto foo2(D *d) -> void_t<decltype(d(std::declval<T*>()))> {}
int main() {
foo1(bar); // Works
foo2<Baz>(bar); // Fails
}
Run Code Online (Sandbox Code Playgroud)
没有问题foo1,bar明确指定了类型.
但是,foo2除了一个版本之外,通过SFINAE禁用自身bar,无法使用以下消息进行编译:
main.cpp:19:5: fatal error: no matching function for call to 'foo2'
foo2<Baz>(bar); // Fails
^~~~~~~~~
main.cpp:15:6: note: candidate template ignored: couldn't infer template argument 'D'
auto foo2(D *d) -> void_t<decltype(d(std::declval<T*>()))> {}
^
1 error generated.
Run Code Online (Sandbox Code Playgroud)
据我所知,C++无法同时解析重载函数的地址并执行模板参数推导.
这是原因吗?有没有办法制作foo2<Baz>(bar);(或类似的东西)编译?
某种一般的答案在这里:Expression SFINAE to override on type of Passed Function Pointer
对于实际情况,不需要使用类型特征,或者decltype()- 好的旧重载解析将为您选择最合适的函数并将其分解为“参数”和“返回类型”。只需枚举所有可能的调用约定
// Common functions
template <class T, typename R> void foo2(R(*)(T*)) {}
// Different calling conventions
#ifdef _W64
template <class T, typename R> void foo2(R(__vectorcall *)(T*)) {}
#else
template <class T, typename R> void foo2(R(__stdcall *)(T*)) {}
#endif
// Lambdas
template <class T, class D>
auto foo2(const D &d) -> void_t<decltype(d(std::declval<T*>()))> {}
Run Code Online (Sandbox Code Playgroud)
将它们包装在模板化结构中可能会很有用
template<typename... T>
struct Foo2 {
// Common functions
template <typename R> static void foo2(R(*)(T*...)) {}
...
};
Zoo2<Baz>::foo2(bar);
Run Code Online (Sandbox Code Playgroud)
尽管如此,成员函数需要更多代码,因为它们具有修饰符 ( const, volatile, &&)
| 归档时间: |
|
| 查看次数: |
555 次 |
| 最近记录: |