C++无法添加到模板内的向量中
C++ cannot add to vector inside template
我正在学习模板。
我有:
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;
}
我在v.push_back(o);
上得到一个编译器错误,它指出:
no matching member function for call to 'push_back'
我认为这是有道理的,为什么,对我来说很模糊,因为这是一个在编译时确定的类型名?
这是否意味着我必须实现自己的push_back()
功能?
Vandevoorde和Josuttis@2003的"C++模板完整指南"仍然适用于C++11吗?
更新1:考虑此编辑:
template<typename SQLObject>
std::vector<SQLObject> executeSelectQueryReturnSQLVector(std::string _recordType,
std::string _sql,
int _rowCount)
{
//typename std::vector<SQLObject> v;
if (_recordType == AppConstants::sSQLFieldObject)
{
std::vector<SQLFieldObject> v;
for(int r=0; r < _rowCount; r++)
{
SQLFieldObject o;
o.putFieldNumber(sqlite3_column_int(statement, 0));
[snip]
v.push_back(o);
}
return v;
}
if (_recordType == AppConstants::sSQLNotificationObject)
{
std::vector<SQLNotificationObject> v;
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;
}
我在两个return v;
上都有编译器错误,比如:
no viable conversion from 'vector<class SQLFieldObject>' to 'vector<class SQLNotificationObject>'
no viable conversion from 'vector<class SQLNotificationObject>' to 'vector<class SQLFieldObject>'
我这样称呼它:
std::vector<SQLFieldObject> _v = executeSelectQueryReturnSQLVector<SQLFieldObject> (AppConstants::sSQLFieldObject, getSQLToSelectFields(), rowCount);
和
std::vector<SQLNotificationObject> _v = executeSelectQueryReturnSQLVector<SQLNotificationObject>(AppConstants::sSQLNotificationObject, getSQLToSelectNotifications(), rowCount);
v
的类型为std::vector<SQLObject>
。o
的类型为SQLFieldObject
。除非有一种自动的方法来投射类型为SQLFieldObject
到SQLObject
的对象
v.push_back(o);
这是不允许的操作。
更新
与更新代码相关的错误为:
executeSelectQueryReturnSQLVector
的返回类型为std::vector<SQLObject>
。return
语句返回std::vector<SQLFieldObject>
或std::vector<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 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;
}
更新:完全编译和链接的源
#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() {}
向量和实例中的类型不同。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);
}
#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;
}
相关文章:
- 有没有办法向这个向量添加元素?
- 这种方式是否可以接受向向量添加unique_ptr?
- 向向量添加元素
- 无法向向量添加回调
- 如何将向量添加到结构中以创建一个库存系统,在该系统中,我可以仅使用一个结构向系统添加多种不同的葡萄酒
- 在一个类中向向量添加元素不适用于其他类
- 以下向 c++ 向量添加元素的方法有什么区别
- 我可以在不推送向量的情况下向向量添加值吗?
- 向向量C++添加对
- 使用单词键将多个行号的向量添加到我的地图中
- 在C++中向指针数组中的向量添加元素
- 要创建一个一开始没有特定维度的类Vector,请在类中创建一个方法,允许向向量添加维度
- 一次向 C++ 向量添加多个元素
- STL - 向存储在 STL 映射中的向量添加值
- 向向量添加向量
- 如何向结构类型的向量添加点
- 为什么我的课'当我向向量添加实例时,会调用s析构函数
- 向c++向量添加新字段
- 在c++中向向量添加对象vs向向量添加指针
- 当Type为unique_ptr时,为向量添加运算符[]