在这种情况下如何进行模板类型推理工作?

时间:2010-07-08 09:40:30

标签: c++ templates type-inference

再一次,我希望C ++有更强的typedef s:

#include <vector>

template<typename T>
struct A {
    typedef std::vector<T> List;
};

template<typename T>
void processList(typename A<T>::List list) {
    // ...
}

int main() {
    A<int>::List list;
    processList<int>(list); // This works.
    processList(list);      // This doesn't.
}

显然,编译器将list视为std::vector<int>而不是A<int>::List,因此无法将其与预期的A<T>::List匹配。

在实际情况中,它是一个较长的类型名称,经常重复,这是一个麻烦。除了让processList接受vector之外,有没有办法让模板类型推断为我工作?

3 个答案:

答案 0 :(得分:5)

  

有没有办法让模板类型推理为我工作?

不,这就是所谓的不可导入的上下文

但是,为什么还需要这个呢?传递序列的惯用方法是迭代器:

template<typename It>
void processList(It begin, It end) {
    typedef typename std::iterator_traits<It>::value_type T;
    // ....
}

int main() {
    A<int>::List list;
    processList(list.begin(), list.end()); // works now
    return 0;
}

(请注意,在您的问题中,您按价值 传递vector ,这是一件坏事。对于迭代器来说,这很好甚至是是首选。)

但是,如果你真的很绝望,你可以让函数演绎任何带有一定数量模板参数的容器:

template<typename T, typename A, template<typename,typename> C>
void processList(C<T,A>& cont) {
    // ....
}

但请注意,这将匹配任何带有两个模板参数的模板。 OTOH,它与std::map之类的容器不匹配,后者具有不同数量的参数。

答案 1 :(得分:0)

知道了。使用继承来创建实际上不同的类型:

template<typename T>
class A : public std::vector<T> {
};

在这种情况下,我不需要非默认构造函数。

答案 2 :(得分:0)

在您的案例中有一个简单的解决方案:

template <class C>
void processList(C const& list)
{
  typedef typename C::value_type value_type;
  BOOST_STATIC_ASSERT_MSG((boost::same_type< C, typename A<value_type>::List >),
    NOT_A_A_LIST_TYPE,
    (C, A<value_type>)
  );
  // do your stuff
}

请注意,C ++ 0x即将到来!

template <typename second>
using TypedefName = SomeType<OtherType, second, 5>;

我想知道这是否有用

template <typename value>
using AList = typename A<value>::List;