1

Consider:

#include <vector>
template<int N> class B {};
template<int N> class A {};

template<int N, template<int> class T>
void doSomething(T<N> const& my_type) {
    //do sth...
}



int main() {
    B<42> b;
    doSomething(b); //OK

    std::vector<A<43>> vec_a;
    doSomething(vec_a); //FAIL: "no matching function for call to 'doSomething'
                        //      "candidate template ignored: could not match N against 'A<43>'"
    return 0;
}

I understand that instead of binding N with 43, the compiler tries to bind it with A<43> (which make sense since vec_a is of type std::vector<A<43>> and not of type std::vector<A><43> or something like that) and logically fails to do so.

What should I do ? (compiler : clang++ 3.3)

4

2 に答える 2

0

ベクトルを受け入れる 2 番目のオーバーロードを追加できます。

#include <vector>

template <typename T, typename A>
void doSomething(std::vector<T, A> const & v)
{
    doSomething(v[3]);
};

本文は他のテンプレートを呼び出し、ベクトルに少なくとも 4 つの要素があると想定します。適切と思われるロジックに置き換えてください。

于 2013-08-08T11:52:34.637 に答える
0

どうやらこれを処理する方法はいくつかありますが、完璧なものはありません。

完璧な方法は、エイリアスを使用することです。

template<int N> using Vec_A = std::vector<A<N>>
Vec_A<43> vec_a;
doSomething(vec_a); //Error!

しかし、エイリアスは単なる省略形であり、実際の型にすぐに置き換えられたようです。これは、GCC ではなく、少なくとも clang++ の場合です。標準は clang と一致しているようです (Grizzly のコメントを参照)。

もちろん、別の方法はオーバーロードすることです(Kerrek SBの回答を参照)が、私はそれが醜いと思います:私にとって、それはテンプレートを使用するポイントを無効にします。

ここで私が好む最後の可能性 (ただし、デフォルトとしてアドバイスはしません) は、公開継承です。

template<int N> class Vec_A : public std::vector<A<N>> {};

この場合、私にとっては問題ない強力なタイピング(ベクターに変換できなくなった)を除いて、ほとんどエイリアスとして機能します。

于 2013-08-08T12:32:12.073 に答える