如何在方法中使用 make "using" 关键字以接受它作为类级别

How to use make "using" keyword within a method to accept it as class level

本文关键字:using 方法 make 关键字      更新时间:2023-10-16

我正在尝试创建一个API,其中包括一个类,该类将使用任意数据类型的向量并按原样"检索"它。我的主要目标是

  1. 在创建类时,用户(使用API)需要提及数据类型。
  2. 在检索矢量时,用户不应提及数据类型。对于Ex:大量的媒介和程序集合它使用此API将它们输出在CSV中。我只会打电话给每个班级的检索方法,它将返回我一个向量,我将以CSV格式打印到文件中。

这是我的代码:

#include<iostream>
#include<vector>
typedef void* handle;
class p{
    public:
        template<typename T>
        void initialize(std::vector<T> p){
            typeC = T;
            h = &p;
        }
        auto returnVec(){
            return *(reinterpret_cast<std::vector<typeC *>>(h));
        }
    private:
        using typeC = int ;
        handle h;
};

int main(){
    std::vector<std::string>v{"Hare","Krishna"};
    p i;
    i.initialize<std::string>(v);
    std::cout<<i.returnVec()[0];
}

现在,我能够存储向量,但是要检索,重新解释铸件应需要知道数据类型。因此,我认为如果可以使用using关键字存储数据类型,则稍后可以在reinterpret_cast中使用它来返回向量。但是我无法做到。如果:

,我可以解决此问题
  1. 我可以以某种方式使此using typeC = T语句影响课程级别,以便在调用returnVec()时仍在作为数据类型存在。
  2. 以某种方式通过A存储数据类型变量。

预先感谢:)

您每次都不能返回其他std::vector<T>,并且您当然不能动态地制作typedef。这是类静态声明的一部分:如果将其捆绑在预编译的对象中,例如,其他编译单元必须可以知道p::typeC是什么。它只是不会以任何修改方式进行,所以我将更广泛地提出问题。

出路是为不同的向量创建一个常见的超类。当然,您不能更改std::vector的定义,但是您可以定义自己的行为,并源自您想要的任何东西。尝试这些行:

#include <vector>
#include <iostream>
class AbstractVector {
  public:
    friend std::ostream& operator<<(std::ostream& os, const AbstractVector& vector) {
      return vector.print(os);
    }
    // other interface fns
    virtual ~AbstractVector() { }
  private:
    virtual std::ostream& print(std::ostream&) const = 0;
};
template<typename T>
class MyVector : public AbstractVector, public std::vector<T> {
  public:
    using std::vector<T>::vector;
    std::ostream& print(std::ostream& os) const override {
      for(auto& x : *this)
        os << x << ' ';
      return os;
    }
};
int main() {
  AbstractVector* av = new MyVector<float>{1.5, 2.5};
  std::cout << *av << 'n';
  delete av;
  av = new MyVector<char>{'a', 'c', 'e'}; // same variable, now it has chars!
  std::cout << *av << 'n'; // but in the "retrieval" I don't need to mention anything extraordinary
  delete av;
}

现在,您可以将其存储在地图上(理想情况下是unique_ptr S或shared_ptr s的形式),而不是std::vector s。

这样做的一个缺点是std::vector没有虚拟驱动器,因此,如果有人认为MyVector IS-A向量并将新实例分配给std::vector<>*,则删除会造成麻烦。一种更合适的方法是使继承protected并重新现台所有您需要的接口。但这是一个起点。

如果您想做的是在您的班级中存储一个矢量或任意容器,则有两种方法可以做到这一点:

template<class Container>
class P {
    Container c;
};
//usage
P<std::vector<int>> obj1;

如果您想进一步拆分矢量数据结构及其模板类型,则可以这样做:

template<class T, template <class , class> class Container>
class P {
     using typeC = Container<T, std::allocator<T>>;
     typeC c;
     const typeC& returnVec() const;
};
//usage
P<int, std::vector> obj2;