为什么术语不计算为接受0个参数的函数

Why is term not evaluating to a function taking 0 arguments?

本文关键字:0个 参数 函数 术语 计算 为什么      更新时间:2023-10-16

当我尝试编译时

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参数调用。。。为什么不编译呢?

问题不在于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++编译器中的一个限制。

对我来说,这很有效。

    typedef int (*X)();
    template<typename T>
    struct is_callable : boolean<sizeof((*(X*)(T*)0)()) >= 0> { };            // works!

因此,编译器似乎不确定在实例化模板类时是否总是将函数指针传递给T!。因此,强制编译器进行显式强制转换。

[编辑]:此外,经过进一步思考,我不明白你真正想做什么。你是想测量一个只接受一个参数的函数指针的大小吗?对于具有不同返回类型的函数,这会有什么不同?为什么常量表达式(sizeof(void*))需要模板?

请查看此线程以了解更多信息函数指针的大小有什么保证?

您可以使用简单的模板专门化。

#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) ": %sn", (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(*)(void):否void(*)(int):否int(*)(void):是int(*)(int):否