ここでのトリック、それはまだ見られていないので、そのレベルでの通話が自身に再帰的になるようfoo
のint
過負荷が、char
過負荷についての考えを持っていないということです。だから、
template <typename... A>
void foo(int a, A... args) { /* only ever calls itself and above*/}
コールfoo(48, '4', '5')
にchars
がint
として解釈されますfoo(int a, A...)
への追加の呼び出しを再帰的になります!
期待通りだから、初期12
を得るでしょうが、あなたは'4'
ため52
の値、および'5'
ため53
の値を取得しますので、あなたは、単に、文字のASCII値を印刷します。 Clangとgccは正しいです。 Visual Studioのバージョンが間違った値を印刷しています。我々は前方私たちのテンプレートを宣言するように周りのあなたのコードを移動し(これは常に良い習慣である)場合、あなた」、今
Called foo(char a, A... args) with 1,2,48,4,5
Called P(T) with 1
Called foo(char a, A... args) with 2,48,4,5
Called P(T) with 2
Called foo(int a, A... args) with 48,4,5
Called foo(int a, A... args) with 52,5
Called foo(char a) with 5
Called P(T) with 3
Called P(T) with 5
Called P(T) with 52
Called P(T) with 48
:(I was able to reproduce with VC 19.00.23506)
はここでコールトレース(instrumented with some help from C++17)です
template<typename T>
void P(T x);
template <typename... A>
void foo(int a, A... args);
template <typename... A>
void foo(char a, A... args);
// actual definitions below...
あなたが望む動作を得るでしょう。そのバージョン(demo)からのスタックトレースは次のとおりです。
Called foo(char a, A... args) with 1,2,48,4,5
Called P(T) with 1
Called foo(char a, A... args) with 2,48,4,5
Called P(T) with 2
Called foo(int a, A... args) with 48,4,5
Called foo(char a, A... args) with 4,5
Called P(T) with 4
Called foo(char a) with 5
Called P(T) with 3
Called P(T) with 5
Called P(T) with 48
リンクコンパイラコードはC++ 14用で、質問にはC++ 11とマークされています。どちらですか? – AndyG
また、リンクされたコードは正しいコードを生成します。あなたは理由の説明を探していますか?おそらく、失敗したコードを提供して、なぜそれが機能しないのかを教えてくれるでしょうか? – AndyG
@AndyGリストされた私の結果は、私が把握できる出力です。 VS2015は私と同じ結果を出力します。はい、正しい結果がどのように生成されているか知りたいと思います。 – q0987