【问题标题】:adding classes to a vector of the same type results in error. is deprecated将类添加到相同类型的向量会导致错误。已弃用
【发布时间】:2021-08-12 08:34:14
【问题描述】:

我正在尝试创建自定义类型的类对象,我想添加到向量中。 是怎么做到的?

这是课程的代码和它给我带来的问题。 它自己的类按预期工作,但是在尝试将这些添加到向量时!

编辑:上传包含所有 cmets 和东西的总代码。

#ifndef TRIPLE_H
#define TRIPLE_H

#include <iostream>

#include <sstream>

#include <initializer_list>

// https://en.cppreference.com/w/cpp/memory/unique_ptr
#include <memory>

using namespace std;

template <typename S, typename T, typename R>
class Triple
   {
      public:
               Triple();
               Triple(S, T, R);
               Triple(Triple &);
               ~Triple();
               const Triple &operator=(const Triple &other);
               //bool operator> (const TRIPLE &lhs, const TRIPLE &rhs);
               //bool operator> (const TRIPLE &lhs);
               //bool operator>(const TRIPLE &right) const;

               string toString();
               string getPerimeter();
               int getPeri();

               S* getFirst();
               S  getFirstvalue(); ///////////////
               T* getSecond();

               void set(S,T,R);

               int getPairCount();

               void setFirst(S);
               void setSecond(T);

      private:
               S *first;
               T *second;
               R *third;
               int *perimeter;
               static int count_of_triples;

   };

template <typename S, typename T, typename R>
int Triple<S, T, R>::count_of_triples=0;

// 0-parameter constructor
template <typename S, typename T, typename R>
Triple<S, T, R>::Triple() : first(NULL), second(NULL), third(NULL), perimeter(0)
   {
      //f = NULL;
      //s = NULL;
      count_of_triples++;
   }

// 2-param constructor
template <typename S, typename T, typename R>
Triple<S, T, R>::Triple(S x, T y, R z) // : first(x), second(y), third(z), perimeter(x + y + z)
{
    first = new S;
    *first = x;
    second = new T;
    *second = y;
    third = new R;
    *third= y;
    perimeter = new int;
    //*perimeter = z;
    //std::cout << "perimeter: " << (x + y + z) << end;
    *perimeter = (x + y + z);
    count_of_triples++;
}

template <typename S, typename T, typename R>
S Triple<S, T, R>::getFirstvalue(){
    if (first!=NULL){
//        if(*first == 0){
//            std::cout << "error" << endl;
//        }
//        else{
//            std::cout << "all ok" << endl;
//        }
        return *first;
    }
    else
        //return NULL; // warning: converting to non-pointer type 'int' from NULL
        return 0;
}

template <typename S, typename T, typename R>
string Triple<S, T, R>::toString()
   {
      stringstream ss;
      ss<<"(";
      if (first==NULL)
         ss<<"NULL";
      else
         ss<<(*first);
      ss<<",";
      if (second==NULL)
         ss<<"NULL";
      else
         ss<<(*second);
      ss<<",";
      if (third==NULL)
         ss<<"NULL";
      else
         ss<<(*third);
      ss<<")";
      return ss.str();
   }

template <typename S, typename T, typename R>
string Triple<S, T, R> ::getPerimeter(){
    stringstream ss;
    ss<<"(";
    if (perimeter==NULL)
       ss<<"NULL";
    else
       ss<<(*perimeter);
    ss<<")";
    return ss.str();
}

template <typename S, typename T, typename R>
int Triple<S, T, R> ::getPeri(){

    return  *perimeter;
}

template <typename S, typename T, typename R>
Triple<S, T, R> ::~Triple()
{
    if(first != NULL)
    delete first;

    if(second != NULL)
    delete second;

    if(third != NULL)
    delete third;

    if(perimeter != NULL)
    delete perimeter;

    first = NULL;
    second = NULL;
    third = NULL;
    perimeter = NULL;

    count_of_triples--;
}

template <typename S, typename T, typename R>
int Triple<S, T, R>::getPairCount(){
    return count_of_triples;
}

template <typename S, typename T, typename R>
void Triple<S, T, R>::set(S x, T y, R z){
    if (first ==__null)
    first = new S;
    *first = x;
    std::cout << "first:" << *first << endl;

    if (second ==__null)
    second = new S;
    *second = y;
    std::cout << "second:" << *second << endl;

    if (third ==__null)
        third = new R;
    *third = z;
    std::cout << "third:" << *third << endl;

    if (perimeter ==__null)
        perimeter = new int;
    *perimeter = (x + y + z);
}

template <typename S, typename T, typename R>
const Triple<S, T, R> &Triple<S, T, R>::operator=(const Triple<S, T, R> &other){

}

template <typename S, typename T, typename R>
bool operator>(Triple<S, T, R> &lhs, Triple<S, T, R> &rhs){
    return lhs.getPeri() > rhs.getPeri();
}

template <typename S, typename T, typename R>
bool operator<(Triple<S, T, R> &lhs, Triple<S, T, R> &rhs){
    return lhs.getPeri() < rhs.getPeri();
}
    

#endif // TRIPLE_H

主要:

#include <iostream>
#include <vector>
#include <algorithm>

//#include <utility>

#include "Triple.h"



    typedef vector<Triple<int, int, int>> triVector;
    
    int main(){
    
    
        Triple<int, int, int> triple;// {1,2,3};
        triple.set(1,2,3);
        std::cout << " ***** " << triple.toString() << endl;
        std::cout << "get perimeter " << triple.getPerimeter() << endl;
        std::cout << "get count " << triple.getPairCount() << endl;
    
        Triple<int, int, int> *triple2 = new Triple<int, int, int>(1,2,5);
        //TRIPLE<int, int, int> *triple2 = new TRIPLE<int, int, int>({1,2,1});
        std::cout << " ***** " << triple2->toString() << endl;
        std::cout << "get perimeter " << triple2->getPerimeter() << endl;
        std::cout << "get count " << triple2->getPairCount() << endl;
    
        Triple<int, int, int> triple3;// {1,2,3};
        triple3.set(1,2,2);
    
        if(triple < *triple2){
            std::cout << "true" << endl;
        }
        else{
            std::cout << "not true" << endl;
        }
    
        std::cout << triple.getFirstvalue() << endl;
    
    
    
        triVector temp;
        temp.push_back(*triple2);
    //    temp.push_back(triple);
    //    temp.push_back(triple3);
    
        for(auto i : temp){
            std::cout << "peri: " << i.getPeri() << endl;
        }
    
        std::cout << "-----------------------------------------" << endl;
        //sort(temp.begin(), temp.end());
    
    //    for(auto i : temp){
    //        std::cout << "peri: " << i.getPeri() << endl;
    //    }
    
    //    std::cout << "-----------------------------------------" << endl;
    
        return 0;
    }

错误:

/usr/include/c++/9/ext/new_allocator.h:145: error: binding reference of type ‘Triple<int, int, int>&’ to ‘const Triple<int, int, int>’ discards qualifiers
In file included from /usr/include/x86_64-linux-gnu/c++/9/bits/c++allocator.h:33,
                 from /usr/include/c++/9/bits/allocator.h:46,
                 from /usr/include/c++/9/string:41,
                 from /usr/include/c++/9/bits/locale_classes.h:40,
                 from /usr/include/c++/9/bits/ios_base.h:41,
                 from /usr/include/c++/9/ios:42,
                 from /usr/include/c++/9/ostream:38,
                 from /usr/include/c++/9/iostream:39,
                 from ../Pair_template/main.cpp:14:
/usr/include/c++/9/ext/new_allocator.h: In instantiation of ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = Triple<int, int, int>; _Args = {const Triple<int, int, int>&}; _Tp = Triple<int, int, int>]’:
/usr/include/c++/9/bits/alloc_traits.h:482:2:   required from ‘static void std::allocator_traits<std::allocator<_CharT> >::construct(std::allocator_traits<std::allocator<_CharT> >::allocator_type&, _Up*, _Args&& ...) [with _Up = Triple<int, int, int>; _Args = {const Triple<int, int, int>&}; _Tp = Triple<int, int, int>; std::allocator_traits<std::allocator<_CharT> >::allocator_type = std::allocator<Triple<int, int, int> >]’
/usr/include/c++/9/bits/stl_vector.h:1189:30:   required from ‘void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = Triple<int, int, int>; _Alloc = std::allocator<Triple<int, int, int> >; std::vector<_Tp, _Alloc>::value_type = Triple<int, int, int>]’
../Pair_template/main.cpp:91:28:   required from here
/usr/include/c++/9/ext/new_allocator.h:145:20: error: binding reference of type ‘Triple<int, int, int>&’ to ‘const Triple<int, int, int>’ discards qualifiers
  145 |  noexcept(noexcept(::new((void *)__p)
      |                    ^~~~~~~~~~~~~~~~~~
  146 |        _Up(std::forward<_Args>(__args)...)))
      |        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

【问题讨论】:

  • 因为vector重新分配了它的内容,vector的内容必须符合Rule Of 3。显示的自定义模板不是。您必须在模板类中实现正确的复制构造函数和赋值运算符。
  • 复制构造函数通常不会修改其参数。
  • 错字Triple(Triple &amp;) ~Triple(); ?接下来的两行。我们怎么知道这是我们应该查看的真实代码? "...debugger 停止在:~Triple()..." 不,是编译器说它不能编译程序。
  • 我很想在格式修复期间修复已发布代码中明显的语法错误,即在 dtor 之前声明非标准复制ctor之后缺少的;。我决定不去。 SO 九年了,我仍然感到困惑,复制/粘贴所谓的问题重现代码如何以某种方式引入“错别字”。小精灵。
  • Using std::tuple。您当前的代码有潜在的内存泄漏和各种其他问题 - 不妨向您展示一些可以实现您正在尝试编码的东西,但要简单得多。

标签: c++ class vector types


【解决方案1】:

你的类声明是错误的:

Triple(Triple &) ~Triple();

应该是:

TRIPLE(TRIPLE&);
~TRIPLE();

您的课程非常奇怪,似乎深受 Java 的启发。不需要所有这些指针,标准的 std::tuple 可能非常适合您正在尝试做的事情。

【讨论】:

  • 我从这里 'stackoverflow.com/questions/43565391/…' 中提取它并将其扩展为练习,这不是问题,它在编译器中是正确的,但是复制和粘贴错误滑过,thanx。跨度>
  • @NaturalDemon 编辑您的问题后,现在明显不同了。
  • 它是一样的,但现在我省略了包含的部分以防止长页面。
【解决方案2】:

感谢@PaulMcKenzie

#include <iostream>
#include <vector>
#include <tuple>
#include <string>
#include <sstream>

template <typename S, typename T, typename R>
class TRIPLE
{
public:
    TRIPLE();
    TRIPLE(S, T, R);
    void set(S, T, R);
    S getFirstvalue();
    std::string toString();

private:
    std::tuple<S, T, R> m_tuple;
};

// 0-parameter constructor
template <typename S, typename T, typename R>
TRIPLE<S, T, R>::TRIPLE() : m_tuple{} {}

// 3-param constructor
template <typename S, typename T, typename R>
TRIPLE<S, T, R>::TRIPLE(S x, T y, R z) : m_tuple{x, y, x} {}

template <typename S, typename T, typename R>
void TRIPLE<S, T, R>::set(S x, T y, R z) 
{
    m_tuple = {x, y, z};
}

template <typename S, typename T, typename R>
S TRIPLE<S, T, R>::getFirstvalue()
{
    return std::get<0>(m_tuple);
}

template <typename S, typename T, typename R>
std::string TRIPLE<S, T, R>::toString()
{
    std::stringstream ss;
    ss << "(" << std::get<0>(m_tuple) << "," << std::get<1>(m_tuple) 
            << "," << std::get<2>(m_tuple) <<  ")";
    return ss.str();
}

typedef std::vector<TRIPLE<int, int, int>> triVector;

int main()
{
    TRIPLE<int, int, int> triple;
    triple.set(1, 2, 3);

    TRIPLE<int, int, int> triple2;
    triple2.set(1, 2, 3);

    TRIPLE<int, int, int> triple3;
    triple3.set(1, 2, 3);

    TRIPLE<int, int, int> triple4;
    triple4.set(1, 2, 3);

    triVector temp;

    temp.push_back(triple2);
    temp.push_back(triple);
    temp.push_back(triple3);

    for (auto i : temp)
    {
        std::cout << "first value: " << i.getFirstvalue() << std::endl;
    }

    return 0;
}

【讨论】:

    猜你喜欢
    • 2016-08-11
    • 2015-12-04
    • 2018-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-02
    • 1970-01-01
    • 2018-03-28
    相关资源
    最近更新 更多