1

次のC++コードは、GNU g ++、LLVM、およびMicrosoft VC6とVC7を除いて、私がスローした他のすべてのC++コンパイラに対して正しくコンパイルおよび実行されます。

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リターン型を持っているかどうかをテンプレート関数からどのように判断できますか?

4

4 に答える 4

3

VC ++ 6に関する限り、この問題を解決するために必要な部分的なテンプレートの特殊化をサポートしていないため、問題が発生します。

于 2009-02-07T19:49:46.837 に答える
3

サイズはこちらをご試着ください

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;
}

動作します。

于 2009-02-07T19:32:00.240 に答える
0

2 つのテンプレートを作成する代わりに、最初のテンプレートのみを使用し、テンプレートの特殊化を使用して 2 番目のテンプレートを定義しようとしましたか?

于 2009-02-07T19:15:14.347 に答える
0

参考までに、これは Microsoft の C++ 2008 Express エディションでコンパイルできます。(助けたかったのですが、コンパイラで問題を再現できません)

于 2009-02-07T19:16:15.873 に答える