静态成员函数指针作为模板参数

Static member function pointer as template argument

本文关键字:参数 函数 指针 静态成员      更新时间:2023-10-16

当使用静态成员函数指针作为模板参数时,我使用最新的 VC++ 编译器(2012 年 11 月 CTP)出现此编译错误:

error C2027: use of undefined type 'wrapper<int (int,int),int A::f1(int,int)>'

但是当使用免费功能时,一切正常。我在 g++ 中查找了一些类似的错误(指向静态成员函数的指针作为 g++ 的模板参数"无效"),但它明确指出参数无效。静态函数有什么不同?

我将函数转换为void(*)(void),因为像<typename T_Ret, typename... T_Args, T_Ret(*)(T_Args...)>这样的构造由于其他一些不相关的原因而无法编译。

struct A
{
    static int f1(int a, int b)
    {
        return a + b;
    }
};
int f2(int a, int b)
{
    return a + b;
}
template <typename Sig, void(*fnc)(void)>
struct wrapper;
template <void(*fnc)(void), typename T_Ret, typename... T_Args>
struct wrapper<T_Ret (T_Args...), fnc>
{
    static bool apply()
    {
        // get some ints here
        int a = 1;
        int b = 2;
        typedef T_Ret (fnc_ptr*)(T_Args...);
        int res = ( (fnc_ptr)fnc )(a, b);
        // do smth with result
        res;
        return true;    // or false
    }
};
int main()
{
    bool res;
    res = wrapper<decltype(A::f1), (void(*)(void))A::f1>::apply();  // error
    res = wrapper<decltype(f2), (void(*)(void))f2>::apply();  // compiles ok
    return 0;
}

编辑:好的,我将问题范围缩小到decltype。当我显式编写类型时,一切正常:

res = wrapper<int(int, int), (void(*)(void))A::f1>::apply();  // compiles ok

你可以尝试这样的事情:

#include <iostream>
using namespace std;
struct A
{
    static int f1(int a, int b)
    {
        return a + b;
    }
};
int f2(int a, int b)
{
    return a + b;
}
template <typename T, T X>
struct wrapper
{
    template <typename... Args>
    static bool value(Args... blargs)
    {
        return X(blargs...) == 3;
    }
};
int main()
{
    bool res;
    res = wrapper<decltype(&A::f1), &A::f1>::value(1,2);
    cout << res << endl;
    return 0;
}

但说真的,这要容易得多:

#include <iostream>
using namespace std;
int main()
{
    bool res;
    res = A::f1(a, b) == 3;
    cout << res << endl;
    return 0;
}

编辑:看起来这是一个编译器错误:http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C-/STLCCSeries6#c634886322325940618

解决方法:

decltype(A::f1)更改为decltype(&A::f1),这会将其输出从 int(int, int) 更改为 int (__cdecl *)(int,int) 。并改变

template <void(*fnc)(void), typename T_Ret, typename... T_Args>
struct wrapper<T_Ret (T_Args...), fnc>

template <void(*fnc)(void), typename T_Ret, typename... T_Args>
struct wrapper<T_Ret (*)(T_Args...), fnc>

工作代码:

struct A
{
    static int f1(int a, int b)
    {
        return a + b;
    }
};
template <typename Sig, void(*fnc)(void)>
struct wrapper;
template <void(*fnc)(void), typename T_Ret, typename... T_Args>
struct wrapper<T_Ret (*)(T_Args...), fnc>
{
    static bool apply()
    {
        // get some ints here
        int a = 1;
        int b = 2;
        typedef T_Ret (*fnc_ptr)(T_Args...);
        int res = ( (fnc_ptr)fnc )(a, b);
        // do smth with result
        res;
        return true;    // or false
    }
};
int main()
{
    bool res;
    res = wrapper<decltype(&A::f1), (void(*)(void))A::f1>::apply();
    return 0;
}