【问题标题】:How to create a vector of Templates?如何创建模板向量?
【发布时间】:2014-11-07 18:18:06
【问题描述】:

我正在尝试构建模板类型的向量,但不断收到错误

 template<class T>
 struct s{

    T val;

    public:
        s(T a)
        {
            val = a;
        };

        friend ostream& operator<<(ostream& os, const T& a);
 };

 template <typename T>
 ostream& operator<< (ostream& os, const T& a){
     return os << a.val;
 }

int main()
{
    s <double> names(4) ;
    s <int> figure(7);
    s <string> word();
    s <vector<int>*> arrays();
    cout << names << endl;
    cout << figure << endl;
    cout << arrays << endl;
    return 0;
}

我一直收到同样的错误 -

request for member 'val' in 'a', which is of non-class type 's<std::vector<int>*>()'|

任何建议将不胜感激

【问题讨论】:

  • 对于初学者,您的结构没有默认构造函数。你应该通过 const 引用传递参数。
  • 哪些参数?那些进入数据类型初始化?

标签: c++ class templates vector


【解决方案1】:
s <vector<int>*> arrays();

这并不实例化一个对象,它声明了一个返回s&lt;vector&lt;int&gt;*&gt;的函数,因此:

cout << arrays << endl;

尝试通过实例化您的模板化 operator&lt;&lt; 来打印出函数指针:

template <typename T>
ostream& operator<< (ostream& os, const T& a){
    return os << a.val;
}

与:

T = s<vector<int>*>(*)();

因此,指向函数a 的指针没有触发错误的.val 字段。

【讨论】:

  • 好的,所以我删除了数组后面的括号。因此,如果我没记错的话,它现在将是 s 类型的 vector 吗?如果我想实现一个返回 val 的 get() 函数,我该怎么做呢?谢谢各位大神帮忙,弄明白了
  • @user3504476: T&amp; get() { return val; } const T&amp; get() const { return val; },准确地说你现在有T = std::vector&lt;int&gt;*,所以val是一个指向整数向量的指针
  • 它给了我一个错误,即 val 没有在范围内声明
  • @user3504476:将此声明放入struct slink here
  • OK 像宝石一样工作。最后一个问题,如果你不介意的话。如果我想实现一个 set 函数,我会以与 get 相同的方式执行它,而是允许一个参数吗?然后将 val 设置为该值?
【解决方案2】:
s <vector<int>*> arrays();

声明一个名为arrays 的函数不接受任何参数并返回s&lt;vector&lt;int&gt;*&gt;。对于 C++11,删除多余的括号或将其替换为 {}。当然,你的s 不支持默认构造,所以你需要给它一个默认构造函数——这可以像给构造函数一个默认参数一样简单:

    s(T a = T())
    {
        val = a;
    }

最好使用成员初始化列表而不是赋值,并使用 const ref 而不是按值,因为T 可能很大:

    s(const T& a = T()) : val(a) { }

在 C++11 中,您应该按值取值并移动 a 改为 val

     s(T a = T()) : val(std::move(a)) { }

还有,

 template <typename T>
 ostream& operator<< (ostream& os, const T& a){
     return os << a.val;
 }

将匹配阳光下的一切。最好只匹配s

 template <typename T>
 ostream& operator<< (ostream& os, const s<T>& a){
     return os << a.val;
 }

最后,

friend ostream& operator<<(ostream& os, const T& a);

结交(并声明)一个简单的函数而不是函数模板。与上面修改的模板operator &lt;&lt; 成为朋友:

    template <typename U>
    friend ostream& operator<<(ostream& os, const s<U>& a);

或者更好的是,删除模板运算符并内联定义友元函数(在类定义中):

    friend ostream& operator<<(ostream& os, const s<T>& a){
        return os << a.val;
    }

这更紧凑,并且还将友谊限制为匹配版本的operator &lt;&lt;,而不是模板的所有实例化。

Demo.

【讨论】:

    【解决方案3】:

    整个问题是这样的

    ClassName InstanceName();
    

    没有使用默认构造函数创建ClassName 的实例,而是声明了一个函数。为了做你想做的事(我假设是用默认构造函数创建实例)使用语法

    ClassName InstanceName;
    

    所以,为了修正你的错误,改变

    s <string> word();
    s <vector<int>*> arrays();
    

    s <string> word;
    s <vector<int>*> arrays;
    

    并将default constructor 添加到您的班级s

    【讨论】:

    • 好的,我已经完成了。我现在创建的向量似乎没有 push_back 功能?我必须给它分配一个大小还是什么?
    • 其原因完全取决于您的实现。
    • 如何向该向量添加值?
    • 我认为,添加元素本身的可能性一定是可以的。问题是:你是否真的创建了一个向量?你的类只包含一个指向向量的指针——最初,你根本没有向量;因此,如果没有向量,就无法添加新元素也就不足为奇了。
    • 那么如果我尊重它,它就会变成一个法线向量?
    猜你喜欢
    • 1970-01-01
    • 2016-10-05
    • 2018-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-09
    • 1970-01-01
    • 2023-01-24
    相关资源
    最近更新 更多