当我尝试编译
时template<bool val>
struct boolean { static const bool value = val; };
template<typename T>
struct is_callable : boolean<sizeof((*(T*)0)()) >= 0> { }; // error!
int main(void) { bool b = is_callable<int (*)()>::value; }
我明白了:
error C2064: term does not evaluate to a function taking 0 arguments
see reference to class template instantiation 'is_callable<T>' being compiled
我很确定int (*)()
可以使用0
参数调用...所以为什么不编译?
答案 0 :(得分:0)
问题不在于使用int()
。您可以从示例中完全删除它并获得相同的错误。当用作非类型模板参数时,问题是sizeof
表达式本身。实施例
template<bool val>
struct boolean { };
template<typename T>
struct is_callable : boolean<sizeof((*(T*)0)()) >= 0> // Error
{
void Test()
{
auto x = sizeof((*(T*)0)()) >= 0; // Compiles
}
};
希望另一个C ++人可以出现并确定这个sizeof
表达式是否仅仅是非法的类型参数,或者这只是MS C ++编译器中的限制。
答案 1 :(得分:0)
对我而言,这是有效的。
typedef int (*X)();
template<typename T>
struct is_callable : boolean<sizeof((*(X*)(T*)0)()) >= 0> { }; // works!
因此,看起来编译器不确定在实例化模板类时总是将函数指针传递给T!因此,强制编译器使用显式转换。
[编辑]:另外,进一步思考,我不明白你真正想做什么。您是否尝试测量一个带有单个参数的函数指针的大小?对于具有不同返回类型的函数,这将如何不同?为什么你需要模板来表示常量表达式(sizeof(void *))?
请查看此主题以获取更多信息 What is guaranteed about the size of a function pointer?
答案 2 :(得分:0)
您可以使用简单的模板专业化。
#include <stdio.h>
template<typename T>
struct func_with_zero_args { static const bool value = false; };
template<>
struct func_with_zero_args <int (*)()> { static const bool value = true; };
#define STRINGIFY(t) "" #t
#define TEST(t) printf(STRINGIFY(t) ": %s\n", (func_with_zero_args<t>::value ? "yes" : "no"));
int
main(int argc, const char* argv[])
{
TEST(void);
TEST(void (*)(void));
TEST(void (*)(int));
TEST(int (*)(void));
TEST(int (*)(int));
return 0;
}
生成(使用g ++(Ubuntu / Linaro 4.7.3-1ubuntu1)4.7.3)
void: no void (*)(void): no void (*)(int): no int (*)(void): yes int (*)(int): no