Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在不知道底层类型的情况下,如何从模板化父类获取值?_C++_Templates_Polymorphism - Fatal编程技术网

C++ 在不知道底层类型的情况下,如何从模板化父类获取值?

C++ 在不知道底层类型的情况下,如何从模板化父类获取值?,c++,templates,polymorphism,C++,Templates,Polymorphism,为了便于说明,给出了这些定义和一些代码: class Child { private: std::string name; public: Child(const std::string & name) name(name) { } } template<typename T> class Parent : public Child { private: T data; public Parent(cons

为了便于说明,给出了这些定义和一些代码:

class Child
{
    private:
    std::string name;

    public:
    Child(const std::string & name) name(name)
    { }
}

template<typename T>
class Parent : public Child
{
    private:
    T data;

    public Parent(const std::string & name, const T & data) : Child(name), data(data)
    { }

    inline GetData() const
    {
        return this->data;
    }
}

std::vector<std::unique_ptr<Child>> values;
values.emplace_back(std::make_unique<Parent<int>>("value a", 4));
values.emplace_back(std::make_unique<Parent<std::string>>("value b", "test"));

for (const auto & v : values)
{
    // I want to access the int and string here!
}
类子类
{
私人:
std::字符串名;
公众:
子(const std::string&name)名称(name)
{ }
}
模板
父类:公共子类
{
私人:
T数据;
公共父(const std::string&name,const T&data):子(name),数据(data)
{ }
内联GetData()常量
{
返回此->数据;
}
}
std::向量值;
值。向后放置(标准::使值唯一(“值a”,4));
值。向后放置(标准::使值唯一(“值b”、“测试”);
用于(常量自动和v:值)
{
//我想在这里访问int和string!
}
如何从这里的基类确定父类中使用的类型

我正在处理的具体场景实际上是,我有一堆
SqlParameterBase
类,其中包含有关存储过程的SQL参数的信息,还有一个
SqlParameter
模板,该模板应该包含在
std::vector
中,并传递到表示存储过程的类中配置,以便可以调用它

但这里的基本问题是,我需要访问底层数据,我希望避免在基类中定义
void*
,以包含指向数据的指针。我希望它尽可能的安全

我对解决此问题的其他设计或方法也持开放态度,因此如果您觉得更好,请随意提出完全不同的建议。

尝试此程序(对于以下问题:如何从这里的基类确定父类中使用的类型?):

输出打印类型。。 但为了看起来更好,还需要做更多的工作

value a of type:i
value b of type:NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
这里“i”表示第一行中的整数

第二个有“基本字符串”。但是周围有一些垃圾

我之所以发布这篇文章,是因为它可能会引发更好的想法

为修改的代码添加了注释

//g++  5.4.0

#include <iostream>
#include <string>
#include <vector>
#include <memory>

//CREATED ANOTHER VARIABLE AND FUNCTION FOR TYPENAME.
//MODIFIED CONSTRUCTOR ACCORDINGLY.
class Child 
{
    private:
    std::string name;
    std::string tyName;

    public:
    Child(const std::string & name,const std::string &tyname):name(name), tyName (tyname)
    { }

    std::string  getName()
    {
        return name;
    }

    std::string  getTypeName()
    {
        return tyName;
    }
};

//MODIFIED CONSTRUCTOR TO PASS THE TYPENAME TO PARENT CLASS.
template<typename T>
class Parent : public Child
{
     private:
     T data;

     public:
     Parent(const std::string & name, const T & data) : Child(name,typeid(data).name()), data(data) 
     { }

     inline T GetData() const
     {
           return this->data;
       }
};



int main()
{
    std::vector<std::unique_ptr<Child>> values;
    values.emplace_back(std::make_unique<Parent<int>>("value a", 4));
    values.emplace_back(std::make_unique<Parent<std::string>>("value b", "test"));


    //GET THE POINTER OF YOUR BASE CLASS.
    //PRINT THE TYPE NAME.
    for (const auto & v : values)
    {
        Child *p = dynamic_cast<Child*>(v.get());
        std::cout<<p->getName()<<" of type:"<<p->getTypeName()<<std::endl;        
    }

    return 0;
}
//g++5.4.0
#包括
#包括
#包括
#包括
//为TYPENAME创建了另一个变量和函数。
//相应地修改了构造函数。
班童
{
私人:
std::字符串名;
std::字符串tyName;
公众:
子(const std::string&name,const std::string&tyname):name(name),tyname(tyname)
{ }
std::string getName()
{
返回名称;
}
std::string getTypeName()
{
返回tyName;
}
};
//修改了构造函数以将TYPENAME传递给父类。
模板
父类:公共子类
{
私人:
T数据;
公众:
父(const std::string&name,const T&data):子(name,typeid(data).name()),数据(data)
{ }
内联T GetData()常量
{
返回此->数据;
}
};
int main()
{
std::向量值;
值。向后放置(标准::使值唯一(“值a”,4));
值。向后放置(标准::使值唯一(“值b”、“测试”);
//获取基类的指针。
//打印类型名称。
用于(常量自动和v:值)
{
Child*p=dynamic_cast(v.get());

std::cout您需要仅存在于派生类型中的子承诺功能(返回类型化数据)。在继承下,这是抽象功能。因此,一组推测性虚拟访问器。这里实际上不需要上传

我会说,如果你不希望Child承诺它返回什么,只是它返回了一些东西,那么看起来你的接口太宽了,你把接口放在使用接口的代码中,比如说用推测性的强制转换等等

可以通过在Child中定义的接口与一组Child进行接口,或者它们具有一些特殊功能,仅在派生中可用,并且必须以这种方式说话


作为Wee补充,您可以考虑一个“代码> STD::vector < /Cord>,而不是完全地修改容器中的类型信息:STD::变体是C++ 17 OFC,所以可能不适合,但是有第三方实现-Boost变体等。

您需要<代码> DyjiCaseCase,但是您真正想要的是一个变体类型。是的,我知道。我需要对父类型进行动态转换。问题是,如果不以硬编码的方式测试每个类型,我无法确定转换到哪个类型。最后,我基本上需要能够确定数据的大小,比如向量中的元素数或字符串的长度;这些成员函数会发生变化基于类型。我考虑了一个模板,只是假设T::size存在,但如果函数的行为在不同类型之间定义不同,则可能会有风险。如果需要确定数据的“大小”,那么添加
virtual std::size\u T size()怎么样const=0;
to
Child
?@aschepler在将我的评论发布到下面的答案之前错过了您的评论。这似乎是最简单的方法,但缺点是我必须为我想要支持的每种数据类型创建类。我可以问一下,您打算对其中的数据做些什么吗?为什么不能在response下这样做家长的责任感?我问的主要是好奇。你说的是抽象功能,这让我思考。使用
虚拟大小\u t GetSize()是否合适=0
在我的父类中,然后在专门用于支持的支持数据的多个子类中实现它?例如,我将有一个
StringChild
和一个
IntChild
,每个都将实现自己获取数据和数据大小的方法。然后我将在循环中切换,并使用枚举跟踪data类型,然后在需要获取数据时动态强制转换。似乎有很多代码,但它使我的界面更窄。经过一些阅读和修改后,
std::variant
实际上非常适合我的需要。我已将我的功能缩减为一组支持