テンプレートのデフォルト引数


151

次のことを許可されている場合:

template <typename T = int>
class Foo{
};

なぜメインで以下を行うことが許可されていないのですか?

Foo me;

ただし、以下を指定する必要があります。

Foo<int> me;

C ++ 11はデフォルトのテンプレート引数を導入し、現在、それらは私の完全な理解にとらわれています。

回答:


188

あなたはしなければならない:

Foo<> me;

テンプレート引数は存在している必要がありますが、空のままにすることができます。

それをfoo単一のデフォルト引数を持つ関数のように考えてください。式fooはそれを呼び出さないでしょうが、呼び出しfoo()ます。引数の構文はまだ存在している必要があります。これはそれと一致しています。


4
私があれば、それはいくつかの不必要な合併症を作成したとし@Pubby Foo かもしれないテンプレート識別子であるか、またはかもしれないデフォルトの引数がありますかどうかに応じて明示的にインスタンス化すること。明示的なインスタンス化構文を保持することをお勧めします。foo単一のデフォルトパラメータを持つ関数のように考えてください。のようfooに呼び出すことはできませんfoo()。これを一貫して維持することは理にかなっています。
ジョセフマンスフィールド

2
@sftrabbit fooでも、引数なしで関数を呼び出すことはできません。Fooただし、引数なしでクラスに名前を付けることができます。
セスカーネギー

4
@aschepler関数を使用すると、テンプレートの引数を関数の引数から推定できます。クラスでは、デフォルトの引数を持つテンプレートクラスを意味するのか、非テンプレートクラスを意味するのかを決定することはできません。
Olaf Dietsche

21
@OlafDietscheしかし、同じ名前のテンプレートクラスと非テンプレートクラスを使用することはできません。そのため、コンパイラは名前が何であるかを調べるだけで判断できるはずです。
セスカーネギー

7
@Pubby標準委員会も同じように質問したと思います。現在、C ++ 17では、<>この場合はもう必要ありません。詳細については、私の答えを確認してください。
Paolo M

53

C ++ 17を使用すると、確かにできます。

この機能はクラステンプレート引数の推定と呼ばれ、テンプレート化された型の変数を宣言する方法に柔軟性を追加します

そう、

template <typename T = int>
class Foo{};

int main() {
    Foo f;
}

は現在、正当なC ++コードです。


5
奇妙な。私のC ++ 17プロジェクトで試してみましたが、機能しませんでした。「テンプレートプレースホルダータイプ 'const MyType'の後には、単純なdeclarator-idが続く必要があります。」GCC 7.3.0を使用しています。
Silicomancer

1
@Silicomancerあなたのコードとコマンドラインを見ずに言うのは難しい...たぶんあなたはここのようなポインターを扱っていますか?
Paolo M

1
Clangはそれを受け入れないようですか?coliru.stacked-crooked.com/a/c5d3c0f90ed263c2
ボーグリーダー

1
@Borgleader明らかに、Coliruはclang 5.0を使用しています。判断すると、この、それはC ++ 17テンプレート引数控除をサポートする必要がありますが、明らかにIDがありません。clang 7.0を使用してwandboxで同じ例を試すと、問題なく動作します。
Paolo M

2
@PaoloMおお、クール、コンパイラバージョンの問題を知ってうれしい。ご覧いただきありがとうございます。
Borgleader

19

あなたはそれをすることはできませんが、あなたはこれを行うことができます

typedef Foo<> Fooo;

そして次に

Fooo me;

デフォルトのタイプとこれに違いはありtypedef Foo<float> Fooo;ますか?:デフォルトのタイプなしで?
qrikko 2016年

5
C ++ 11っぽい方法は言うことでしょうusing Fooo = Foo<>;
エイドリアンW

18

次のものを使用できます。

Foo<> me;

そしてint、あなたのテンプレートの引数があります。山括弧は必須であり、省略できません。


理にかなっていると感謝しますが、以下に示すように、なぜ型指定が存在しないのですか?
user633658 2013年

@ user633658:「型指定子」という意味ですか?よくわかりません
Andy Prowl

とにかく、空の山かっこが必要な理由については、私は推測しかできません。テンプレートの名前の使い方だけで考えられる曖昧さを排除することについてですが、正確なことはわからないことを告白する必要があります理由
Andy Prowl 2013年

<>の要件は、コンパイラーのパーサーが、fooと呼ばれるものではなく、fooと呼ばれるテンプレート化されたクラスを参照していることを判別できるようにすることであると強く思います。
Mac
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.