C++ C++;无法添加到模板内的向量

C++ C++;无法添加到模板内的向量,c++,templates,vector,compiler-errors,C++,Templates,Vector,Compiler Errors,我正在学习模板 我有: template<typename SQLObject> std::vector<SQLObject> executeSelectQueryReturnSQLVector(std::string _recordType, std::string _sql,

我正在学习模板

我有:

template<typename SQLObject>
std::vector<SQLObject> executeSelectQueryReturnSQLVector(std::string _recordType,
                                                             std::string _sql,
                                                             int _rowCount)
{
    typename std::vector<SQLObject> v;

    if (_recordType == AppConstants::sSQLFieldObject)
    {
        for(int r=0; r < _rowCount; r++)
        {
            SQLFieldObject o;

            o.putFieldNumber(sqlite3_column_int(statement, 0));
            [snip]
            v.push_back(o);
        }
    }

    if (_recordType == AppConstants::sSQLNotificationObject)
    {
        for(int r=0; r < _rowCount; r++)
        {
            SQLNotificationObject o;

             o.putNotificationID(sqlite3_column_int(statement, 0));
             [snip]
             v.push_back(o);
        }
    }

    return v;
}
我在
和return v上都得到了编译器错误如:

no viable conversion from 'vector<class SQLFieldObject>' to 'vector<class SQLNotificationObject>'

no viable conversion from 'vector<class SQLNotificationObject>' to 'vector<class SQLFieldObject>'
从“vector”到“vector”没有可行的转换
从“vector”到“vector”没有可行的转换
我这样称呼它:

std::vector<SQLFieldObject> _v = executeSelectQueryReturnSQLVector<SQLFieldObject>    (AppConstants::sSQLFieldObject, getSQLToSelectFields(), rowCount);
std::vector _v=executeSelectQueryReturnSQLVector(AppConstants::sSQLFieldObject,getSQLToSelectFields(),rowCount);

std::vector\u v=executeSelectQueryReturnSQLVector(AppConstants::sSQLNotificationObject,getSQLToSelectNotifications(),rowCount);

v
的类型是
std::vector
o
的类型是
SQLFieldObject
。除非有自动方式将类型为
SQLFieldObject
的对象强制转换为
SQLObject
,否则

v.push_back(o);
这是不允许的操作

更新

 #include <vector>
 #include <string>

 struct SQLFieldObject {};
 struct SQLNotificationObject {};

 // A template class that returns an appropriate string based on the
 // typename used to instantiate.
 template <typename SQLObject> struct RecordTypeChooser;

 // Specialization for returning the record type for SQLFieldObjects.
 template <> struct RecordTypeChooser<SQLFieldObject>
 {
    static std::string getRecordType() { return "SQLFieldObject"; }
 };

 // Specialization for returning the record type for SQLNotificationObjects.
 template <> struct RecordTypeChooser<SQLNotificationObject>
 {
    static std::string getRecordType() { return "SQLNotificationObject"; }
 };

 // A template class that constructs an object and returns it.
 // The object type is based on the typename used to instantiate.
 template <typename SQLObject> struct ObjectCreator;

 // Specialization for constructing SQLFieldObjects.
 template <> struct ObjectCreator<SQLFieldObject>
 {
    static SQLFieldObject createObject()
    {
       SQLFieldObject o;
       // o.putFieldNumber(sqlite3_column_int(statement, 0));
       return o;
    }
 };

 // Specialization for constructing SQLNotificationObjects.
 template <> struct ObjectCreator<SQLNotificationObject>
 {
    static SQLNotificationObject createObject()
    {
       SQLNotificationObject o;
       // o.putNotificationID(sqlite3_column_int(statement, 0));
       return o;
    }
 };



 template<typename SQLObject>
 std::vector<SQLObject> executeSelectQueryReturnSQLVector(std::string _recordType,
                                                          std::string _sql,
                                                          int _rowCount)
 {
    typename std::vector<SQLObject> v;

    // Not sure whether you need this any more.
    if (_recordType == RecordTypeChooser<SQLObject>::getRecordType())
    {
       for(int r=0; r < _rowCount; r++)
       {
          v.push_back(ObjectCreator<SQLObject>::createObject());
       }
    }

    return v;
 }


 void foo()
 {
    std::vector<SQLFieldObject> v1 = executeSelectQueryReturnSQLVector<SQLFieldObject>("SQLFieldObject",
                                                                                       "",
                                                                                       10);

    std::vector<SQLNotificationObject> v2 = executeSelectQueryReturnSQLVector<SQLNotificationObject>("SQLNotificationObject",
                                                                                       "",
                                                                                       10);
 }

 int main() {}
与更新代码相关的错误有:

executeSelectQueryReturnSQLVector的返回类型是
std::vector
return
语句返回
std::vector
std::vector
。嗯,返回的对象的类型与函数签名中的返回类型不匹配

更优雅地处理模板:

 // A template class that returns an appropriate string based on the
 // typename used to instantiate.
 template <typename SQLObject> struct RecordTypeChooser;

 // Specialization for returning the record type for SQLFieldObjects.
 template <> struct RecordTypeChooser<SQLFieldObject>
 {
    static std::string getRecordType() { return AppConstants::sSQLFieldObject; }
 };

 // Specialization for returning the record type for SQLNotificationObjects.
 template <> struct RecordTypeChooser<SQLNotificationObject>
 {
    static std::string getRecordType() { return AppConstants::sSQLNotificationObject; }
 };

 // A template class that constructs an object and returns it.
 // The object type is based on the typename used to instantiate.
 template <typename SQLObject> struct ObjectCreator;

 // Specialization for constructing SQLFieldObjects.
 template <> struct ObjectCreator<SQLFieldObject>
 {
    static SQLFieldObject createObject()
    {
       SQLFieldObject o;
       o.putFieldNumber(sqlite3_column_int(statement, 0));
       return o;
    }
 };

 // Specialization for constructing SQLNotificationObjects.
 template <> struct ObjectCreator<SQLNotificationObject>
 {
    static SQLNotificationObject createObject()
    {
       SQLNotificationObject o;
       o.putNotificationID(sqlite3_column_int(statement, 0));
       return o;
    }
 };



 template<typename SQLObject>
 std::vector<SQLObject> executeSelectQueryReturnSQLVector(std::string _recordType,
                                                          std::string _sql,
                                                          int _rowCount)
 {
    typename std::vector<SQLObject> v;

    // Not sure whether you need this any more.
    if (_recordType == RecordTypeChooser<SQLObject>::getRecordType())
    {
       for(int r=0; r < _rowCount; r++)
       {
          v.push_back(ObjectCreator<SQLObject>::createObject());
       }
    }

    return v;
 }
//一个模板类,它根据
//用于实例化的typename。
模板结构记录类型选择器;
//用于返回SQLFieldObjects的记录类型的专门化。
模板结构记录类型选择器
{
静态std::string getRecordType(){返回AppConstants::sSQLFieldObject;}
};
//用于返回SQLNotificationObjects的记录类型的专门化。
模板结构记录类型选择器
{
静态std::string getRecordType(){返回AppConstants::sSQLNotificationObject;}
};
//构造并返回对象的模板类。
//对象类型基于用于实例化的类型名。
模板结构ObjectCreator;
//用于构造SQLFieldObjects的专门化。
模板结构ObjectCreator
{
静态SQLFieldObject createObject()
{
sqlfieldo;
o、 putFieldNumber(sqlite3_column_int(语句,0));
返回o;
}
};
//用于构造SQLNotificationObjects的专门化。
模板结构ObjectCreator
{
静态SQLNotificationObject createObject()
{
sqlnotificationobjecto;
o、 putNotificationID(sqlite3_column_int(语句,0));
返回o;
}
};
模板
std::vector executeSelectQueryReturnSQLVector(std::string\u记录类型,
std::string\u sql,
整数(行计数)
{
std::vector v;
//不确定你是否还需要这个。
如果(_recordType==RecordTypeChooser::getRecordType())
{
对于(int r=0;r<_rowCount;r++)
{
v、 向后推(ObjectCreator::createObject());
}
}
返回v;
}
更新:完全编译和链接的源代码

 #include <vector>
 #include <string>

 struct SQLFieldObject {};
 struct SQLNotificationObject {};

 // A template class that returns an appropriate string based on the
 // typename used to instantiate.
 template <typename SQLObject> struct RecordTypeChooser;

 // Specialization for returning the record type for SQLFieldObjects.
 template <> struct RecordTypeChooser<SQLFieldObject>
 {
    static std::string getRecordType() { return "SQLFieldObject"; }
 };

 // Specialization for returning the record type for SQLNotificationObjects.
 template <> struct RecordTypeChooser<SQLNotificationObject>
 {
    static std::string getRecordType() { return "SQLNotificationObject"; }
 };

 // A template class that constructs an object and returns it.
 // The object type is based on the typename used to instantiate.
 template <typename SQLObject> struct ObjectCreator;

 // Specialization for constructing SQLFieldObjects.
 template <> struct ObjectCreator<SQLFieldObject>
 {
    static SQLFieldObject createObject()
    {
       SQLFieldObject o;
       // o.putFieldNumber(sqlite3_column_int(statement, 0));
       return o;
    }
 };

 // Specialization for constructing SQLNotificationObjects.
 template <> struct ObjectCreator<SQLNotificationObject>
 {
    static SQLNotificationObject createObject()
    {
       SQLNotificationObject o;
       // o.putNotificationID(sqlite3_column_int(statement, 0));
       return o;
    }
 };



 template<typename SQLObject>
 std::vector<SQLObject> executeSelectQueryReturnSQLVector(std::string _recordType,
                                                          std::string _sql,
                                                          int _rowCount)
 {
    typename std::vector<SQLObject> v;

    // Not sure whether you need this any more.
    if (_recordType == RecordTypeChooser<SQLObject>::getRecordType())
    {
       for(int r=0; r < _rowCount; r++)
       {
          v.push_back(ObjectCreator<SQLObject>::createObject());
       }
    }

    return v;
 }


 void foo()
 {
    std::vector<SQLFieldObject> v1 = executeSelectQueryReturnSQLVector<SQLFieldObject>("SQLFieldObject",
                                                                                       "",
                                                                                       10);

    std::vector<SQLNotificationObject> v2 = executeSelectQueryReturnSQLVector<SQLNotificationObject>("SQLNotificationObject",
                                                                                       "",
                                                                                       10);
 }

 int main() {}
#包括
#包括
结构SQLFieldObject{};
结构SQLNotificationObject{};
//一个模板类,它根据
//用于实例化的typename。
模板结构记录类型选择器;
//用于返回SQLFieldObjects的记录类型的专门化。
模板结构记录类型选择器
{
静态std::string getRecordType(){返回“SQLFieldObject”;}
};
//用于返回SQLNotificationObjects的记录类型的专门化。
模板结构记录类型选择器
{
静态std::string getRecordType(){返回“SQLNotificationObject”;}
};
//构造并返回对象的模板类。
//对象类型基于用于实例化的类型名。
模板结构ObjectCreator;
//用于构造SQLFieldObjects的专门化。
模板结构ObjectCreator
{
静态SQLFieldObject createObject()
{
sqlfieldo;
//o.putFieldNumber(sqlite3_column_int(语句,0));
返回o;
}
};
//用于构造SQLNotificationObjects的专门化。
模板结构ObjectCreator
{
静态SQLNotificationObject createObject()
{
sqlnotificationobjecto;
//o.putNotificationID(sqlite3_column_int(语句,0));
返回o;
}
};
模板
std::vector executeSelectQueryReturnSQLVector(std::string\u记录类型,
std::string\u sql,
整数(行计数)
{
std::vector v;
//不确定你是否还需要这个。
如果(_recordType==RecordTypeChooser::getRecordType())
{
对于(int r=0;r<_rowCount;r++)
{
v、 向后推(ObjectCreator::createObject());
}
}
返回v;
}
void foo()
{
std::vector v1=executeSelectQueryReturnSQLVector(“SQLFieldObject”,
"",
10);
std::vector v2=executeSelectQueryReturnSQLVector(“SQLNotificationObject”,
"",
10);
}
int main(){}

向量和实例中的类型不同。Vector只保存原始类(由于内存分配问题,无法保存子类)。但是,您可以存储指向类的指针。考虑这一点:

typedef boost::shared_ptr<SQLObject> SQLObjectPtr;
typedef std::vector<SQLObjectPtr> SQLObjectPtrVector;

...
for(int r=0; r < _rowCount; r++)
{
    SQLFieldObjectPtr o(new SQLFieldObject);

    ...
    v.push_back(o);
}
typedef boost::sharedptrsqlobjectptr;
typedef std::vector SQLObjectPtrVector;
...
对于(int r=0;r<_rowCount;r++)
{
SQLFieldObjectPtr o(新的SQLFieldObject);
...
v、 推回(o);
}
#包括
#包括
使用名称空间std;
结构A
{
在里面
typedef boost::shared_ptr<SQLObject> SQLObjectPtr;
typedef std::vector<SQLObjectPtr> SQLObjectPtrVector;

...
for(int r=0; r < _rowCount; r++)
{
    SQLFieldObjectPtr o(new SQLFieldObject);

    ...
    v.push_back(o);
}
#include <iostream>
#include <vector>

using namespace std;

struct A
{
    int a;
};

struct B
{
    char b;
};

template<typename T>
vector<T> fun(char type)
{
    if (type == 'A')
    {
        vector<T> v;
        // generate objects of A and append to v
        return v;
    }
    else
    {
        vector<T> v;
        // generate objects of B and append to v
        return v;
    }
}

int main()
{
    vector<A> v = fun<A>('A');

    return 0;
}