我有一个类需要传递两个单独的模板:
template <typename T>
class AwesomeClass
{
TList *theList;
typename list <T>::iterator theiterator;
public:
template <typename TList>
AwesomeClass(TList &list)
{
theList = &list;
};
}
你可能会告诉它它基本上为STL提供了一个包装器(我必须这样做)。理想情况下,我不希望通过对象声明传递这两个模板,如下所示:
typedef AwesomeClass<int, BaseClass<int> > BaseClassIteratorInt;
并宁愿逃避:
typedef BaseClass<int> ListFromBaseClassInt;
typedef AwesomeClass<int> BaseClassIteratorInt;
BaseClassIteratorInt newInt(ListFromBaseClassInt)
(这就是上面代码的意思)
然而,我一直收到错误:
错误C2143:语法错误:缺少';'在'*'之前
对于变量TList * theList。
我需要为cist提供TList的类型,有没有办法做到这一点?
额外步骤:
好的,我现在有格式代码:
template <typename Container>
class AwesomeClass
{
public:
typedef typename std::common_type< Container > value_type;
bool firstUse;
Container *theList;
typename Container::iterator theIterator;
explicit AwesomeClass(Container &list):theList(&list)
{
};
}
这是使用common_type来解决阻止行
的编译器错误typedef typename Container::value_type value_type;
由于value_type不是全局命名空间的一部分而进行编译。
但是我有一个编译器错误,编译器声称它需要一个';'在它之前。
任何人都可以看到有什么问题吗?
答案 0 :(得分:1)
我认为你不需要两个模板参数。
template <class Container>
class AwesomeClass {
public:
// you can use this typedef to access the value type
typedef typename Container::value_type value_type;
AwesomeClass(Container &list): theList(&list) {}
private:
Container *theList;
typename Container::iterator theiterator;
};
int main() {
// you can use typedef if you like
typedef std::list<int> intList;
intList list{1, 2, 3};
AwesomeClass<intList> newInt(list);
}
答案 1 :(得分:0)
听起来你需要TList
的前向声明:你在声明它之前使用它,所以编译器无法知道它。
答案 2 :(得分:0)
您必须先将TList
声明为模板参数,然后才能在其他声明中使用它。
template <typename TList, typename T>
class AwesomeClass {
TList* theList;
/* ... */
};
此外,您不需要声明第二个模板参数T
,而是获取类似的类型:
using value_type = typename TList::value_type;
其次,您不必在ctor中使用模板推理。
// template <typename TList> // Unnecessary if the template parameter is already declared
AwesomeClass(TList& list) {
theList = &list;
}
第三,你把分号放在ctor之后而不是在类范围的末尾。
/* ... */
AwesomeClass(TList& list) {
theList = &list;
}; // Unnecessary to put semicolon after function definitions.
} // Although, you need semicolon here.
看起来您希望能够在创建AwesomeClass
对象时自动推断模板参数的类型。但是, class 模板参数可以不自动推断,只有 function 模板可以做到。
要完成模板参数的自动扣除,您可以创建一个函数,该函数返回带有推导参数的AwesomeClass
,例如
template <typename TList>
auto make_awesome(TList& list) -> AwesomeClass<TList, typename TList::value_type> {
return {list};
}
修改强>
如果你想要的是一个存储指向任何类型的std::list
的指针的类,那么你需要推导的只是元素类型。但是,您只能存储指向std::list
容器的指针,而不是指向std::vector
的指针。
template <typename T>
class AwesomeClass {
public:
AwesomeClass(std::list<T>& c) {
c_ = &c;
}
private:
std::list<T>* c_;
typename std::list<T>::iterator iter_;
};
int main() {
typedef AwesomeClass<int> BaseClassIteratorInt;
BaseClassIteratorInt b{l};
}
答案 3 :(得分:0)
用
template <typename T, typename TList> class AwesomeClass
class AwesomeClass
{
TList *theList;
typename list<T>::iterator theiterator;
public:
explicit AwesomeClass(TList &list) : theList(&list) {}
};
你可以做些什么来推断构造的类型是一个免费的功能:
template<typename T, typename TList>
AwesomeClass<T, TList> make_AwesomeClass(TList& tlist)
{
return AwesomeClass<T, TList>(tlist);
}
这样称呼:
auto awesomeClass = make_AwesomeClass<int>(mylist);