如何将多个模板传递到类中

时间:2014-02-28 10:35:04

标签: c++ templates

我有一个类需要传递两个单独的模板:

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不是全局命名空间的一部分而进行编译。

但是我有一个编译器错误,编译器声称它需要一个';'在它之前。

任何人都可以看到有什么问题吗?

4 个答案:

答案 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);