Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 接受函数指针的方法上的可变模板_C++_Templates_C++11_Variadic Templates - Fatal编程技术网

C++ 接受函数指针的方法上的可变模板

C++ 接受函数指针的方法上的可变模板,c++,templates,c++11,variadic-templates,C++,Templates,C++11,Variadic Templates,在我看来,下面的代码应该可以正常工作,但它会产生 C2738: could not deduce template argument for 'Type'. 2013年 template <typename ReturnType, typename...Args> uint GetParameterSize(ReturnType(*method)(Args...)) { return ParameterSize<Args...>(); } template &

在我看来,下面的代码应该可以正常工作,但它会产生

C2738: could not deduce template argument for 'Type'.
2013年

template <typename ReturnType, typename...Args>
uint GetParameterSize(ReturnType(*method)(Args...))
{
    return ParameterSize<Args...>();
}

template <typename Type, typename...Remaining>
uint ParameterSize()
{
    uint output = sizeof(Type);

    if (sizeof...(Remaining) > 0)
    {
        output += ParameterSize<Remaining...>();
    }

    return output;
}

void MyMethod3(int a, char b, int c )
{
}

// Elsewhere
uint size = GetParameterSize(&MyMethod3);
我的意思是,它看起来很简单,我认为它应该能工作。编译器怎么能不推断参数呢?我是新的可变模板,所以我可能会错过一些东西,但一些帮助将不胜感激。谢谢

  if (sizeof...(Remaining) > 0)
    {
        output += ParameterSize<Remaining...>();
    }

例如,我能想到的最简单的修复方法是调用重载解析:

template <typename Type>
constexpr unsigned ParameterSize(int)
{
    return sizeof(Type);
}

template <typename Type, typename...Remaining>
constexpr unsigned ParameterSize(...)
{
    return sizeof(Type) + ParameterSize<Remaining...>(42);
}

template <typename ReturnType, typename...Args>
constexpr unsigned GetParameterSize(ReturnType(*method)(Args...))
{
    return ParameterSize<Args...>(42);
}

void MyMethod3(int a, char b, int c )
{
}

int main()
{
    // Elsewhere
    unsigned size = GetParameterSize(&MyMethod3);
}
模板
constexpr无符号参数大小(int)
{
返回sizeof(类型);
}
模板
constexpr无符号参数大小(…)
{
返回sizeof(Type)+参数size(42);
}
模板
constexpr unsigned GetParameterSize(ReturnType(*方法)(Args…)
{
返回参数size(42);
}
无效MyMethod3(整数a、字符b、整数c)
{
}
int main()
{
//别处
unsigned size=GetParameterSize(&MyMethod3);
}

省略号使第二个重载比第一个重载更难匹配
int
(例如
42
)类型的参数,这就是歧义(
ParameterSize(42)
)的解决方法。

对于代码不工作的原因,还有其他答案,因此我将给您一个替代方法。由于您似乎在累积
sizeof(Type)
以获得存储函数参数所需的总堆栈大小,因此我将这样做:

    #include <iostream>
    #include <algorithm>

    template <class ... Args>
    unsigned ParameterSize()
    {
        unsigned sizes[sizeof...(Args)] = {sizeof(Args)...};
        return std::accumulate(std::begin(sizes), std::end(sizes), 0);
    }

    template <typename ReturnType, typename...Args>
    uint GetParameterSize(ReturnType(*method)(Args...))
    {
        return ParameterSize<Args...>();
    }

    void MyMethod(int,int,int){}

    int main()
    {
        std::cout << GetParameterSize(&MyMethod) << std::endl;
    }
#包括
#包括
模板
无符号参数size()
{
无符号大小[sizeof…(Args)]={sizeof(Args)…};
返回std::累计(std::开始(大小),std::结束(大小),0);
}
模板
uint GetParameterSize(返回类型(*方法)(参数…)
{
返回参数size();
}
void MyMethod(int,int,int){}
int main()
{

std::难道我看不到
ParameterSize()的任何参数吗
这将允许它推断
类型
。提供的函数指针的参数类型将是提供给
参数大小
的参数包,不是吗?我想我明白了您的意图。您希望
参数…
int a,char b,int c
。我将执行
静态断言()
GetParameterSize
中的
GetParameterSize
以查看
Args…
是否实际设置。我猜可能不是。它是。
sizeof…(Args)
GetParameterSize
中生成3个。要查看这一点,我必须注释掉对
ParameterSize
的递归调用。当
剩余的
为空时,您“调用”(实例化)在第一个版本
ParameterSize()
中,它没有指定
Type
,并且无法推断
Type
,因此会出现错误。在第二个版本(带有重载)中,当调用
ParameterSize()时
,这两种重载都是可行的,而且都不是更专业的;因此存在歧义。使用
constexpr
,如果您使用的是Visual Studio,则至少需要VS2013;否则只需删除
constexpr
。先生,您很好。我不是这方面的超级粉丝。但它可以满足我的需要,而无需重新构建s、 这只是一个例子,实际的问题比这个大一点,但你肯定让我达到了我需要的程度。谢谢。
template<typename ... Args>
struct ParameterSize;   
{
   static const uint value = 0;
};

template<typename Type, typename... Remain>
struct ParameterSize<Type, Remain...>
{
   static const uint value = sizeof(Type) + ParameterSize<Remain...>::value;
};

template <typename ReturnType, typename...Args>
uint GetParameterSize(ReturnType(*method)(Args...))
{
    return ParameterSize<Args...>::value;
}
template <typename Type>
constexpr unsigned ParameterSize(int)
{
    return sizeof(Type);
}

template <typename Type, typename...Remaining>
constexpr unsigned ParameterSize(...)
{
    return sizeof(Type) + ParameterSize<Remaining...>(42);
}

template <typename ReturnType, typename...Args>
constexpr unsigned GetParameterSize(ReturnType(*method)(Args...))
{
    return ParameterSize<Args...>(42);
}

void MyMethod3(int a, char b, int c )
{
}

int main()
{
    // Elsewhere
    unsigned size = GetParameterSize(&MyMethod3);
}
    #include <iostream>
    #include <algorithm>

    template <class ... Args>
    unsigned ParameterSize()
    {
        unsigned sizes[sizeof...(Args)] = {sizeof(Args)...};
        return std::accumulate(std::begin(sizes), std::end(sizes), 0);
    }

    template <typename ReturnType, typename...Args>
    uint GetParameterSize(ReturnType(*method)(Args...))
    {
        return ParameterSize<Args...>();
    }

    void MyMethod(int,int,int){}

    int main()
    {
        std::cout << GetParameterSize(&MyMethod) << std::endl;
    }