2016-09-23 12 views
8
class A 
{ 
    struct B{}; 
public: 
    static void test(A::B){} 
}; 

struct C 
{ 
    template<class T> 
    operator T() 
    { 
     return T(); 
    } 
}; 

int main() 
{ 
    A::test(C()); 
} 

このコードは、clang 3.7、gcc 5.1およびvC++ 14.2で機能します。
2つの問題、
1.テンプレートでA:Bと推測できるのはなぜですか? (とてもスマート!)
私が知る限り、テンプレートはパラメータの代わりにreturn文で型を推論します。
N4606 12.3.2 6 A conversion function template shall not have a deduced return type (7.1.7.4).に興味があるものが見つかりました(ただし、7.1.7.4は理解しがたいのでこれ以上の情報はありません)。
2.なぜ変換関数テンプレートA :: Bにアクセスできるのでしょうか?C++ - 変換関数のテンプレート控除、なぜこれは機能しますか?

ありがとうございました。

答えて

4
  1. なぜテンプレートがタイプA:Bであると推測できるのですか? test()A::Bがかかるため

(!とてもスマート)、あなたはA::BCを変換する方法が必要です。 [over.match.conv]にある変換関数による初期化を試みることができます。

変換関数Sとその基本クラスを考慮します。非明示変換 Sと降伏タイプT内に隠されていない関数、またはTから 標準変換シーケンス(13.3.3.1.1)を介してタイプ変換できるタイプは候補関数です。

我々は[temp.conv]に記載のテンプレート控除を行う:

をテンプレート引数控除があるタイプで( それPを呼び出す)変換関数テンプレートの戻り型を比較す​​ることにより行われます14.8.2.5に記述されているように、変換の結果として必要とされる(Aと呼ぶ; については、8.6,13.3.1.5、および13.3.1.6を参照)。

基本的に、我々はA::Bするtemplate <class T> operator T()Tを推測します。これは順調な変換シーケンスであり、実行可能な唯一の変換シーケンスなので、それが起こります。

引用した行は、「返品タイプ」についての返品タイプでautoまたはdecltypeです。これはここでは起こりません。

  1. なぜ変換関数がテンプレートA :: Bにアクセスできるのですか?

アクセスルールは厳密には名前に関するものです。 の名前はBで、名前はAに限定されています。しかし、という名前のにはアクセスしていません。タイプを直接推測しています。

Bのコンストラクタはpublicであるため、変換関数の本体も整形式であるため、コードに関するすべてが整形式です。少し物事をoversimplifyする

+0

ああ、私はそれを得た。 ''返される型は '7.1.7.4'であるが、 '変換関数型は返される型が決まらない'。つまり、 '7.1.7.4'は'変換関数 'に慣れていません。私は '7.1.7.4'の部分を読む必要はありません。 – Caesar

+0

'name'ではなく' type'でアクセスコントロールに関する詳しい情報はどこで入手できますか? – Caesar

+0

@Caesarタイプのアクセス制御などはありません。 – Barry

0

を内部クラスや関数のプライベートを作るだけで、クラスの名前や機能が唯一のクラスで使用できることを意味し、それはそれ以外の場合はアクセスできません。クラスの外にあるプライベートクラスまたは関数の名前を使用するコードを書くことはできません。

示されたコードA::Bは、クラス外のどこにも使用されていません。

これは、同じ正確な理由のために、あまりにも動作します:

class A { 

    class B {}; 

public: 

    B foo(); 
}; 


int main() 
{ 
    A a; 

    auto bar=a.foo(); 
    return 0; 
} 

auto作品。 A::Bは機能しません。

関連する問題