1

次のコードは、gcc および VC11 Nov CTP でも動作しますが、VC11 RTM ではコンパイルに失敗します。

template<typename T>
struct A {
    typedef typename T::Type BreakMe;
    T x;
};
struct B { typedef int Type; };

template<typename T>
struct C {
    static A<T> f(A<T> a) {
        return A<decltype(a.x)>();
    }
    static auto g(A<T> a) -> A<decltype(a.x)> {
        return A<decltype(a.x)>();
    }
};

int main(int argc, char* argv[])
{
    C<B>::f(A<B>());
    C<B>::g(A<B>());
    return 0;
}

VC11 RTM は、decltype が戻り値のテンプレート パラメーターとして渡されると失敗するようです。「T=unknown」と見なされます。f内部で decltype を使用しているにもかかわらず、正常にコンパイルされることに注意してください。

これは RTM のコンパイラのバグですか? もしそうなら、それを回避する方法はありますか?

4

1 に答える 1

2

回避策を見つけました。

秘訣は、戻り値の型全体をヘルパー構造体に渡し、そこでテンプレートを強制的に解決することです。typedefdecltyped テンプレート パラメーターがまだ不明であるように見えるため、ヘルパー構造体の戻り値の型を -ing するだけでは十分ではないようです。ただし、ヘルパー構造体の関数の戻り値の型として設定すると、型が強制的に解決されるようです。次に、この関数の戻り値の型を簡単に取得できます (再び decltype を使用)。

これを回避マクロでラップすると、

#if defined(_MSC_VER) && _MSC_VER <= 1700
namespace workarounds {
  template<typename T>
  struct resolve_template {
    static T ret();
  };
}
#define RESOLVE_TEMPLATE(A) decltype(::workarounds::resolve_template<A>::ret())
#else
#define RESOLVE_TEMPLATE(A) A
#endif

これを上記に追加すると、http://rise4fun.com/Vcpp/JplIが得られます。

于 2013-04-17T20:18:21.777 に答える