2009-09-24 10 views
24

記事でクレームを何度も読んでいる - 私はStackoverflowにこの質問を追加し、コミュニティに尋ねる - 次のコードは移植可能ですか?標準ライブラリコンテナには、追加のオプションのテンプレートパラメータがありますか?

template<template<typename T, typename Alloc> class C> 
void f() { 
    /* some code goes here ... */ 
} 

int main() { 
    f<std::vector>(); 
} 

std::vectorを提供する実装は、実際には2つのよく知られたもの以外の追加、不履行テンプレートパラメータを持つことが許されていませんか?これは、2つのテンプレートパラメータを仮定しているので、上記のコードを不正にします。このようなクレームの例については、最後の段落in this articleを参照してください。

答えて

22

私はあいまいさがありません

を言うこれ、以下issue reportを発見しました。標準は書かれているように明確である。ライブラリの実装者は、標準ライブラリクラスにテンプレートパラメータを追加することはできません。これは、 "as if"ルールに該当しないため、標準が実装者にこれを行うための明示的なライセンスを与えた場合にのみ許可されます。これには標準の変更が必要です。

LWGは、テンプレートテンプレートパラメータや標準ライブラリクラステンプレートの特殊化に関するユーザーコードを壊す可能性があるため、この変更を禁止しました。

実装が他のオプションのパラメータを追加する可能性がある書籍や人々は間違っているようです。

1

17.4.4 [lib.conforming]のサブセクションを確認してください。

17.4.4.3/3は、「グローバルまたは非メンバ関数は、追加のデフォルト引数を取ると宣言することはできません」と述べていますが、17.4.4.4/2は、記述されたメンバ関数の署名を、追加パラメータにはデフォルトが設定されているためです。

テンプレートのセクションはありませんので、もし17.4.4.3/3を提供する必要があると感じたら、余分なテンプレートパラメータは逆の言い方を許しているようです。

+0

[OK]を、決して心 - 問題の報告書は明らかに比べて優れています私の推測:P – me22

0

私もこの主張を見てきました。しかし。

私は決してこれを行う実装を見たことがありません。私はAndrei Alexandrescuが、ステロイドのアロケータタイプ(のようなものだが、ちょうどstd::allocatorのようなもの)を使用することを考えていたことを覚えているようだ。しかし、これでもまだあなたのf()が機能し続けるでしょう。これは実装に最も近いことです。

0ポインタは、すべてのビットが0に設定された値で必ずしも表現される必要はないという主張と同じカテゴリに入ると思います。たとえベンダーが実際にその自由を持っていても(私は、両側の主張があるので、知っている)、それらは基本的にすべての既存のコードを破るので、それを使用することはありません。

私はそれ以来、心配しないことに決めました。

+0

誰かが問題を提出して、[pretty printer](http://louisdx.github.com/cxx-prettyprint/)のプルリクエストをしました。これらの余分な引数は実際にはMSVCコードしたがって、私が提供した特殊化を作りました。:-( –

2

信じられないほど、私は最近、「C++テンプレート:完全ガイド」を読んでいたし、最後の本は111ページの以下のマーク:テンプレートテンプレート引数が正確のパラメータと一致するパラメータを持つクラステンプレートでなければなりません

それが代用するテンプレートテンプレートパラメータテンプレートテンプレート引数のデフォルトのテンプレート引数は無視されます(ただし、テンプレートテンプレートパラメータにデフォルトの引数がある場合は、テンプレートのインスタンス化中に考慮されます)。

この本を信じるならば、テンプレートテンプレート引数のデフォルトのテンプレート引数は無視されるので、標準以外のデフォルトのパラメータがstd :: vectorに追加されているあなたの例は正しいかもしれません。

現実世界のテストとして、私は(成功した)++グラムで、次のとVisual Studio 2008(不一致のパラメータに失敗した)コンパイルさ:

template<typename T1, typename T2, typename T3 = float> 
class MyClass 
{ 
public: 
    T1 v1; 
    T2 v2; 
    T3 v3; 
}; 

template<template<typename T1, typename T2> class C> 
void f() 
{ 
    C<int,double> *c = new C<int,double>(); 
} 

int main() 
{ 
    f<MyClass>(); 
    return 0; 
} 
+2

"テンプレートテンプレート引数のデフォルトテンプレート引数は無視されます"というのは、パラメータにデフォルト引数があってもそのデフォルト引数はu sedと対応するパラメータは、デフォルトの引数を持たないかのようにカウントされます。したがって、implに3つのパラメータを持つベクトルがあり、3番目にデフォルトの引数がある場合、vectorをテンプレートのテンプレート引数として渡すのは、デフォルトの引数が存在しない場合と同じです。 –

+0

g ++ 4.4.1でサンプルをコンパイルしようとしましたが、g ++ 4.1はコードを受け入れますが、これを拒否します。これはGCCのバグだったようです。 –

+0

そのことを明確にしてくれてありがとう - 少し違った解釈をしていました。私は4.1でコンパイルしました(古いFedora VMです)。 – csj

関連する問題