c++ - 使用返回类型调用模板化成员指针函数时出错

标签 c++ templates variadic-templates pointer-to-member template-argument-deduction

template<typename T, typename F, typename ...Args>
auto f(F h, Args&&... args) -> decltype(h(args...)) {
    T* t = new T(); // Don't worry, my actual code doesn't do this
    return (t->h)(args...);
}

struct G {
    int g() {
        return 5;
    }
};

int main() {
    int k = f<G>(&G::g);
}

Microsoft 的编译器说 error C2672: 'f': no matching overloaded function founderror C2893: Failed to specialize function template 'unknown-type f(F,Args &&...)' .

Clang 的编译器说 note: candidate template ignored: substitution failure [with T = G, F = int (G::*)(), Args = <>]: called object type 'int (G::*)()' is not a function or function pointererror: no matching function for call to 'f' .

我很确定int (G::*)()是一个函数指针...?我错过了什么? (在我添加返回类型之前,所有这些都工作正常。)

最佳答案

I'm pretty sure int (G::*)() is a function pointer ... ? What am I missing?

不完全是:int (G::*)()是指向非静态方法的指针。这不是完全相同的东西,需要一些不同的语法来调用它。

所以,而不是

return (t->h)(args...);

你应该添加一个*并调用h()如下

return (t->*h)(args...);
// ........^  add this *

decltype()也是错误的。如果您至少可以使用 C++14,则可以避免使用它而只需使用 auto作为返回类型

template <typename T, typename F, typename ...Args>
auto f (F h, Args&&... args) {
    T* t = new T(); 
    return (t->*h)(args...);
}

否则,如果你必须使用C++11,你可以包括<utility>并使用 std::declval()如下

template <typename T, typename F, typename ...Args>
auto f(F h, Args&&... args) -> decltype((std::declval<T*>()->*h)(args...)) { 
    T* t = new T(); // .................^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    return (t->*h)(args...);
}

但是还有另一种方式来写你的f()功能:推导返回的类型(因此避免了 autodecltype()std::declval() )和 h() 的参数

你可以写f()如下

template<typename R, typename T, typename ... As1, typename ... As2>
R f(R(T::*h)(As1...), As2 && ... args) {
    T* t = new T();
    return (t->*h)(args...);
}

并且您避免显式显示 G输入调用它

int k = f(&G::g);
// .....^^^^^^^^   no more explicit <G> needed

因为 T模板类型是从参数 &G::g 推导出来的.

关于c++ - 使用返回类型调用模板化成员指针函数时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55067069/

相关文章:

c++ - 函数的嵌套模板参数

C++ Pimpl 习惯用法、类模板和 void 模板参数

c++ - 与阅读不同格式的数字字符有关的问题

c++ - 为什么 push_back 进入 vector<vector<int>> 导致段错误?

c++ - 在这个 C++ 代码中,std::string 可以被模板参数 T 替换吗?如果可以,Meyer 关于其性能成本的论点是否仍然适用?

c++ - 调试可变参数

c++组合来自两个(或更多)参数包的值

c++ - C++如何对右值引用进行模板推导?

c++ - 从派生类调用带有抽象基类的类——安全

c++ - 为什么只有一个参数的可变参数模板与非可变参数模板不同?