15

次の関数について考えてみます。

template <typename A, typename B>
auto Min(A&& a, B&& b)
        -> decltype(a < b ? std::forward<A>(a) : std::forward<B>(b))
{
    return a < b ? std::forward<A>(a) : std::forward<B>(b);
}

フラグメントMin(0, 1)により、テンプレートはとしてインスタンス化されMin<int, int>ます。不思議なことに、Min私のコードのwith g ++とclangのマングル名は_Z3MinIiiEDTqultfp_fp0_cl7forwardIT_Efp_Ecl7forwardIT0_Efp0_EEOS0_OS1_ (別名:)ですdecltype (({parm#1}<{parm#2})?((forward<int>)({parm#1})) : ((forward<int>)({parm#2}))) Min<int, int>(int&&, int&&)。つまり、戻り型を推測するために使用される式は、マングルされた名前の一部です_Z3MinIiiET_OS0_OT0_個人的に、私は:(別名:)の線に沿ってもう少し正気な何かを期待していましたint Min<int, int>(int&&, int&&)なぜそうではないのですか?


decltypeg ++は、これらの形式が両方ともあるため、実際に必要な場合にのみ式を配置するよう_Z3Maxiiです。

  • auto Max(int x, int y) -> int
  • auto Max(int x, int y) -> decltype(0)
4

3 に答える 3

6

gcc はマングリングに「Italium C++ ABI」を使用しており、次のように指定されています。

のオペランド式がインスタンス化に依存decltypeしない場合、結果の型は直接エンコードされます。例えば:

      int x;
      template<class T> auto f(T p)->decltype(x);
        // The return type in the mangling of the template signature
        // is encoded as "i".
      template<class T> auto f(T p)->decltype(p);
        // The return type in the mangling of the template signature
        // is encoded as "Dtfp_E".
      void g(int);
      template<class T> auto f(T p)->decltype(g(p));
        // The return type in the mangling of the template signature
        // is encoded as "DTcl1gfp_E".

3 番目の例は、インスタンス化に依存するため、式全体を直接エンコードする OP の縮小バージョンです。インスタンス化依存は次のように定義されます。

式が型依存または値依存である場合、または型依存または値依存の部分式がある場合、その式はインスタンス化依存です。たとえば、pが型依存の識別子である場合、式sizeof(sizeof(p))は型依存でも値依存でもありませんが、インスタンス化依存です (テンプレート引数の置換後にp不完全であることが判明した場合、無効になる可能性があります)。タイプ)。同様に、ソース フォームにインスタンス化に依存する式が含まれている場合、ソース コードで表現される型はインスタンス化に依存します。たとえば、型フォームdouble[sizeof(sizeof(p))](p型依存の識別子を持つ) はインスタンス化依存です。

重要な点は、インスタンス化に依存する式は「置換後に無効になる可能性がある」ということです。これが、マングリングで評価されない形式のままになる可能性が高い理由です。

于 2012-11-08T19:12:08.413 に答える
4

関数テンプレートをオーバーロードする場合、これらの関数テンプレートによって生成される関数 (関数テンプレートの特殊化と呼ばれます) は異なる必要があります。したがって、C++ 標準では、関数テンプレートの特殊化のシグネチャに、特殊化が生成された元の関数テンプレートのシグネチャが含まれることを指定しています。

そうしないと、両方のテンプレートが同じ関数型を持つ関数をインスタンス化すると、衝突します。

于 2012-11-08T19:51:54.813 に答える