【发布时间】:2016-07-11 17:05:41
【问题描述】:
我编写了许多模板函数。示例:
template <typename T>
inline int Foo(T* t, unsigned char** p, size_t* size, size_t (*MyHandler)(T*))
{
...
}
template <>
inline int Foo<Bar>(Bar* t, unsigned char** p, size_t* size, size_t (*MyHandler)(Bar*))
{
...
}
如果我使用显式模板参数调用这些函数,那么一切正常,即
Foo<Bar>(&myBar, pBuffer, size, FooFoo<Bar>);
FooFoo<T> 是一个不同的模板函数
如果用户不需要跟踪类型,那将是非常有利的。所以我想使用以下语法:
Foo(&myBar, pBuffer, size, FooFoo);
但是,这条线却造成了一对
- C2784:无法从 'Bar *' 推导出 'T *' 的模板参数
- C2796:不能使用函数模板 'size_t FooFoo(T *) 作为函数参数
与Foo 一样,存在一个专门化FooFoo<Bar>
据我所知,应该可以推导出 T,因为第一个参数的类型为 T* - 或者该函数指针是否与推导混淆?
任何提示将不胜感激。
更新 3 根据@Yakk 建议的更改请求的 MCVS 最终有效!
#include <stdio.h>
struct Bar
{
int a;
int b;
int c;
};
template<class T>struct id_t{typedef T type;};
template <typename T>
inline size_t FooFoo(T* t)
{
printf("FooFoo calculating size of T...\r\n", sizeof(T));
return sizeof(T);
}
template <>
inline size_t FooFoo<Bar>(Bar* t)
{
printf("FooFoo calculating size of Bar...\r\n", sizeof(Bar));
return sizeof(Bar);
}
template <typename T>
inline int Foo(T* t, unsigned char** p, size_t* size, typename id_t<size_t (*)(T*)>::type MyHandler)
{
printf("Foo telling size of T: %u\r\n", MyHandler(t));
return 0;
}
template <>
inline int Foo<Bar>(Bar* t, unsigned char** p, size_t* size, typename id_t<size_t (*)(Bar*)>::type MyHandler)
{
printf("Foo telling size of Bar: %u\r\n", MyHandler(t));
return 0;
}
int main(int argc, char* argv[])
{
int i;
Bar myBar;
Foo<Bar>(&myBar, nullptr, 0, FooFoo<Bar>); // works
Foo<int>(&i, nullptr, 0, FooFoo<int>); // works
Foo(&myBar, nullptr, 0, FooFoo<Bar>); // works
Foo(&i, nullptr, 0, FooFoo<int>); // works
Foo(&myBar, nullptr, 0, FooFoo); // error C2896: 'int Foo(T *,unsigned char **,size_t *,size_t (__cdecl *)(T *))' : cannot use function template 'size_t FooFoo(T *)' as a function argument
// error C2784: 'int Foo(T *,unsigned char **,size_t *,size_t (__cdecl *)(T *))' : could not deduce template argument for 'T *' from 'Bar *'
Foo(&i, nullptr, 0, FooFoo); // error C2896: 'int Foo(T *,unsigned char **,size_t *,size_t (__cdecl *)(T *))' : cannot use function template 'size_t FooFoo(T *)' as a function argument
//error C2784: 'int Foo(T *,unsigned char **,size_t *,size_t (__cdecl *)(T *))' : could not deduce template argument for 'T *' from 'int *'
return 0;
}
非常感谢!
【问题讨论】:
-
只是好奇,但你试过
Foo(&myBar, pBuffer, size, FooFoo<Bar>);吗? -
无法使用 g++ 5.1 (TDM)、clang 或 VC2015 重现 - 请在您的帖子中添加 Minimum, Complete and Verifiable example 和有关您的编译器的详细信息,这样我们就不必猜测出了什么问题。
-
@Holt 我已经更新了详细信息,编译器是 MSVC 2012
-
@antipattern 感谢您的更新,您的 MCVE 有一个小错误(我猜第一次返回应该是
sizeof(T)而不是T)。我没有 MSVC2012,但我确认您提供的示例在 MSVC2015 上编译并运行良好,不知道它是否符合标准…… -
@Holt 感谢您的测试,这是一件好事,因为我这里只有这个旧版本,没有别的。我担心这毕竟是不可能的。
标签: c++ templates visual-studio-2012