1

考虑:

#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;
}

我知道编译器没有将 N 与 43 绑定,而是尝试将其与 A<43> 绑定(这是有道理的,因为 vec_a 是类型std::vector<A<43>>而不是类型std::vector<A><43>或类似的东西)并且逻辑上没有这样做。

我应该怎么办 ?(编译器:clang++ 3.3)

4

2 回答 2

0

显然有几种方法可以处理这个问题,但没有一个是完美的。

完美的方法是使用别名,即

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

但 alias 只是一种速记,似乎很快就被真实类型取代了。至少 clang++ 是这种情况,GCC 不是。该标准似乎与 clang 一致(参见 Grizzly 评论)。

另一种方法当然是重载(请参阅 Kerrek SB 答案),但我觉得它很难看:对我来说,它破坏了使用模板的意义。

最后一种可能性,我更喜欢这里(但我不建议作为默认值)是公共继承:

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

它几乎充当别名,除了更强的类型(不能再转换为向量),在这种情况下这对我来说是可以的。

于 2013-08-08T12:32:12.073 回答
0

您可以添加第二个接受向量的重载:

#include <vector>

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

主体将调用另一个模板,并假设向量至少有四个元素。用你认为合适的逻辑替换它。

于 2013-08-08T11:52:34.637 回答