5

前の質問

この質問を自己完結型にするために、前の質問のコードを繰り返します。以下のコードは、gcc 4.8.3 を使用してコンパイルされた場合、コンパイルされ、警告を発行しません。と-std=c++1y。ただし、-std=c++0xフラグを指定してコンパイルすると、警告が発行されます。前の質問の文脈では、コードは gcc 4.9.0 を使用してコンパイルされないことが述べられていました。残念ながら、現時点では がどのようautoに実装されているか完全には理解できていません。したがって、誰かが次の質問に答えてくれれば幸いです。

1)。以下のコードは、C++14 標準に関して有効な C++ ですか?

2)。はいの場合、このコードは良いスタイルと見なされますか? そうでない場合、なぜですか?

3)。C++11 コンパイラを使用しているときに、以下のコードがコンパイルされて (時々) 動作するのはなぜですか? または、なぜそれが常に機能するとは限らないのですか? 動作を妨げる特定のフラグ/オプション/設定はありますか?

template<int N> auto getOutputPort2();
template<> auto getOutputPort2<0>();
template<> auto getOutputPort2<1>();

template<>
auto getOutputPort2<0>()
{
    return std::unique_ptr<int>(new int(10));
}

template<>
auto getOutputPort2<1>()
{
    return std::unique_ptr<string>(new string("qwerty"));
}
4

1 に答える 1

6

1)。以下のコードは、C++14 標準に関して有効な C++ ですか?

はい、私が知る限りでは。多くの場合、それを禁止するものは何もないため、証明するのが少し難しい場合があります. ただし、最近のドラフト (N4296 以降) [dcl.spec.auto]/13 の例を見ることができます。

template <typename T> auto g(T t) { return t; } // #1
template auto g(int);                           // OK, return type is int
template char g(char);                          // error, no matching template
template<> auto g(double);                      // OK, forward declaration with
                                                // unknown return type

同じパラグラフで次のように規定されています。

プレースホルダー型を使用する宣言された戻り値の型を持つ関数または関数テンプレートの再宣言または特殊化も、推定型ではなく、そのプレースホルダーを使用する必要があります。

したがって、関数テンプレートの明示的な特殊化では、戻り値の型推定を使用する必要があります。さまざまな専門分野のさまざまな戻り値の型を禁止するものは見つかりません。同様に、C++98 では、戻り値の型をテンプレート引数に依存させることで、(同じプライマリ テンプレートの) 関数テンプレートの特殊化の異なる戻り値の型を実現できます。メタプログラミングを使用することで、基本的に、戻り値の型推論を使用して異なる特殊化に対して無関係な戻り値の型を指定する場合と同じことを実現できます。


3)。以下のコードが (時々) C++11 コンパイラを使用してコンパイルおよび動作するように見えるのはなぜですか?

OP のコードは、C++11 では形式が正しくありません。通常の関数 (非ラムダ) の戻り型推定は、C++14 で導入された機能です。このコード スニペットを含むプログラムは形式が正しくありません。ただし、標準では、実装 (コンパイラ) が不適切な形式のプログラムを拒否する必要があるとは規定していません。[intro.compliance]/2.2 で次のように述べているだけです。

プログラムに診断可能なルールの違反が含まれている場合 [...] 適合する実装は、少なくとも 1 つの診断メッセージを発行する必要があります。

そして/8で

適合する実装には、整形式プログラムの動作を変更しないという条件で、拡張機能 (追加のライブラリ関数を含む) が含まれる場合があります。実装は、この国際標準に従って不適切な形式の拡張機能を使用するプログラムを診断する必要があります。ただし、そうした後は、そのようなプログラムをコンパイルして実行できます。

(したがって、実装はこのプログラムを拡張機能として受け入れることができます。)

g++4.8.3 は、診断メッセージとしてカウントされる警告を発行します。g++4.9 はエラーを発行します。これは診断メッセージでもあります。どちらも準拠しています。を指定すること-Werrorで、g++4.8.3 にこのプログラムを拒否するように伝えることができます。(gcc 開発者に、なぜ警告からエラーに変更したのかを尋ねる必要があります。)

于 2014-12-24T01:31:18.283 に答える