15

型ではないテンプレート パラメーターは、明らかに型ではないものです。次に例を示します。

template<int x>
void foo() { cout << x; }

その場合以外にも選択肢はありますので、こちらの素晴らしい回答intを参考にしたいと思います。

さて、私を悩ませていることが 1 つあります。構造体です。検討:

struct Triple { int x, y, z; };

Triple t { 1, 2, 3 };

template<Triple const& t>
class Foo { };

ここで、通常の非型参照セマンティクスを使用して、次のように記述できます。

Foo<t> f;

ここで注目に値するのは、それがor でさえt ないということです。これは内部リンケージを意味するためです。これは基本的に、行がコンパイルされないことを意味します。として宣言することでそれをバイパスできます。それ自体は少し奇妙かもしれませんが、私が本当に不思議に思ったのは、なぜこれが不可能なのかということでした:constexprconsttconst extern

Foo<Triple { 1, 2, 3 }> f;

コンパイラから非常にまともなエラーが発生します。

エラー:左辺値ではないためTriple{1, 2, 3}、型の有効なテンプレート引数ではありません。const Triple&

Triple許可されていないため、値でテンプレートに指定することはできません。ただし、その小さなコード行の実際の問題を理解できません。構造体を値パラメーターとして使用できない理由は何ですか。3 つの s を使用できる場合int、3 つの int の構造体を使用しないのはなぜですか? 些細な特殊メンバーしか持たない場合は、3 つの変数だけを扱う場合と実際には変わらないはずです。

4

3 に答える 3

14

このビットだけを機能させるのは簡単ですが、構造体テンプレート パラメーターの使用が、他のテンプレート パラメーターと同じ状況で機能しないことに不満を言う人がいます (部分的な特殊化を検討するか、 をどうするかを考えてくださいoperator==)。

私の意見では、ケーキ全体を手に入れるにはあまりにも面倒です. このほんの少しの作業を行うだけでは、次のようなものよりも多くの力が得られません。これには、箱から出してあらゆる種類のもの (部分的な特殊化を含む) を操作できるという追加の利点があります。

template <int X, int Y, int Z>
struct meta_triple {
    // static value getters
    static constexpr auto x = X;
    static constexpr auto y = Y;
    static constexpr auto z = Z;
    // implicit conversion to Triple 
    constexpr operator Triple() const { return { X, Y, Z }; }
    // function call operator so one can force the conversion to Triple with
    // meta_triple<1,2,3>()()
    constexpr Triple operator()() const { return *this; }
};
于 2013-04-09T08:26:49.093 に答える
7

tとして定義してconst extern、外部リンケージを与えることができます。次に、構成が機能します。

struct Triple { int x, y, z; };

const extern Triple t { 1, 2, 3 };

template<Triple const& t>
class Foo { };

Foo<t> f;

実例

一時を参照テンプレート パラメーターに渡すことができない理由は、パラメーターが参照であるためです。テンプレート パラメータがconst int&で、 を渡そうとすると、同じエラーが発生します7

編集

int3 つの s と 3 つの s を含む struct の違いintは、型のすべてのリテラルintが実際には同じ値である (の出現回数はすべて77 つだけ) のに対し、構造体への各コンストラクター呼び出しは概念的に新しいインスタンスを作成することです。次の架空の例を見てください。

template <Triple t>
struct Foo {};

Foo<Triple {1, 2, 3}> f1;
Foo<Triple {1, 2, 3}> f2;

これらの 2 つのコンストラクター呼び出しを同じテンプレートのインスタンス化に「一致させる」には、余分な複雑さが生じると思います。

于 2013-04-09T08:18:20.720 に答える