再一次,我希望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
之外,有没有办法让模板类型推断为我工作?
答案 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;