4

以前に同様の質問をしたことがありますが、部分的に専門化することで機能させることができることを理解しました。しかし、可変個引数テンプレートの基本を理解するために、このようなコードを変更しました。

template<typename T, typename... args>
struct counter{
static const int value= 1+ counter<args...>::value;
};

template<typename T>
struct counter<T>{
static const int value = 0;
};

エラー: 「申し訳ありませんが、実装されていません: 'args ...' を固定長の引数リストに展開することはできません」

これはバグであり、gcc 4.7.0 で修正されていることを理解しています

したがって、これをすべて修正するには、テンプレートを部分的に特殊化するトリックまたはその他を使用する必要があります。

template<typename... Args> struct counter;

template<>
struct counter<> {
static const int value = 0;
};

template<typename T, typename... Args>
struct counter<T, Args...> {
static const int value = 1 + counter<Args...>::value;
};

実際の質問:コードが機能するように部分的な特殊化がここで行う特殊効果を本当に知りたいですか、それとも部分的な特殊化が問題をどのように解決するかを尋ねる必要がありますか? (2 番目のバージョンでバグがヒットしないのはなぜですか?)。動機付けの問題と例を含む説明は非常に役立ちます.

4

2 に答える 2

3

template<typename...>2 番目のバージョンでは、プライマリ テンプレートが として宣言されているため、つまり可変個引数であるため、バグが回避されます。バグの鍵は、エラー メッセージにあります

したがって、任意の数の引数を受け入れるように調整されてcounter<Args...>::valueいるため、2 番目のケースで機能します。ただし、プライマリ テンプレートが として宣言されている最初のケースでは、コンパイラは固定長部分 ( ) と可変長部分 ( new )に分離する必要があります。おそらくそれは、GCC のバージョンに実装されていないまさにその機能です。countertemplate<typename T, typename... args>argsTargs

<T, Args...>2 番目のケースの特殊化を<typename...>プライマリ テンプレートと一致させることができる機構が何であれ、固定長拡張に再利用できると信じる理由はありません。

(最後に、C++11 機能のサポートは GCC によって「実験的」とマークされているため、何が機能し、何が機能しないか、ましてやその理由方法については期待できません。この種の質問は、私たちではなく、GCC 開発者がメーリング リストで合理的に回答する必要があります。私たちは読者を気にしません。)

于 2011-10-13T13:54:11.283 に答える
-1

特別なコードは最初のケースです。たまたま特定のコンパイラのバグに遭遇しました。

于 2011-10-10T21:54:23.110 に答える