VC6和VC7中判断函数是不是有void返回类型的方法

Posted

技术标签:

【中文标题】VC6和VC7中判断函数是不是有void返回类型的方法【英文标题】:Need way to determine whether function has void return type in VC6 and VC7VC6和VC7中判断函数是否有void返回类型的方法 【发布时间】:2009-02-07 19:05:42 【问题描述】:

以下 C++ 代码可以为 GNU g++、LLVM 和我扔给它的所有其他 C++ 编译器正确编译和运行,Microsoft VC6 和 VC7 除外:

template<typename A, typename B> int HasVoidReturnType(A(*)(B))  return 0; 
template<typename B> int HasVoidReturnType(void(*)(B))  return 1; 
void f(double) 
int foo()  return HasVoidReturnType(f); 

VC6和VC7编译失败报错:

f.cpp(4) : error C2667: 'HasVoidReturnType' : none of 2 overloads have a best conversion
    f.cpp(2): could be 'int HasVoidReturnType(void (__cdecl *)(B))'
    f.cpp(1): or       'int HasVoidReturnType(A (__cdecl *)(B))'
    while trying to match the argument list '(overloaded-function)'
f.cpp(4) : error C2668: 'HasVoidReturnType' : ambiguous call to overloaded function
    f.cpp(2): could be 'int HasVoidReturnType(void (__cdecl *)(B))'
    f.cpp(1): or       'int HasVoidReturnType(A (__cdecl *)(B))'
    while trying to match the argument list '(overloaded-function)'

与其争论什么编译器的优点是对的,我如何使用 VC6 和 VC7 从模板函数中确定函数是否具有 void 返回类型?

【问题讨论】:

【参考方案1】:

就 VC++ 6 而言,你搞砸了,因为它不支持部分模板专业化,而这正是你解决这个问题所需要的。

【讨论】:

VC++ 6 几乎不能称为“C++ 编译器”。 VC++ 7.0 也很烂。另一方面,VC++ 7.1 是一个相当不错的 C++ 编译器。这里的版本编号系统很不幸。【参考方案2】:

试穿一下尺寸

template<typename FuncPtrType>
struct DecomposeFuncPtr;

template<typename ReturnType, typename ArgType>
struct DecomposeFuncPtr<ReturnType(*)(ArgType)> 
  typedef ReturnType return_type;
;

template<typename T>
struct is_void 
  enum  value = 0 ;
;

template<>
struct is_void<void> 
  enum  value = 1 ;
;

template<typename T>
int HasVoidReturnType(T dontcare) 
  return is_void< typename DecomposeFuncPtr<T>::return_type >::value;

它应该避免混淆 VC6/7 的重载。

嗯。抱歉,我无法使用 VC6/7 对其进行测试。不过,我记得之前在 VC 中使用带有模板的函数指针遇到了问题。由于我们知道 A,B 适用于您原来的功能,我想知道是否类似:

template<typename T>
struct is_void 
  enum  value = 0 ;
;

template<>
struct is_void<void> 
  enum  value = 1 ;
;

template<typename A, typename B>
int HasVoidReturnType(A(*)(B)) 
  return is_void<A>::value;

会工作的。

【讨论】:

VC7: t.cpp(5) : error C2065: 'ReturnType' : undeclared identifier ... t.cpp(15) : error C2913: 显式特化; 'is_void is_void' 不是类模板 试试模板 char (& HasVoidReturnType(A(*)(B)) )[is_void::value + 1];然后 sizeof(HasVoidReturnType(fun)) 可以根据它是否返回 void 来告诉您 1 或 2。也许这也适用于vc6?它会在编译时工作:) 最后一种方式是我一开始会如何编写它——但可能是因为与模板专业化相比,我不了解重载解决方案。【参考方案3】:

您是否尝试过只使用第一个模板并使用模板专业化来定义第二个模板,而不是创建两个模板?

【讨论】:

【参考方案4】:

仅供参考,这可以在 Microsoft 的 C++ 2008 Express 版本上编译。 (我很想帮忙,但无法在我的编译器上重现该问题)

【讨论】:

以上是关于VC6和VC7中判断函数是不是有void返回类型的方法的主要内容,如果未能解决你的问题,请参考以下文章

Java中,构造函数没有返回值。请问没有返回值和返回值类型为void,有啥区别?

函数签名

C语言中void main和int main有啥区别

php类型的相关函数,运算符,条件判断,循环

构造函数用于创建类的实例对象,构造函数名应与类名相同,返回类型为void.

如果方法的返回类型是 Void,我应该返回啥? (不是无效的!)