Template Template Parameter and Template Traits
Hello to all, i have create a generic data manager which uses several data type format and different database but encountered an error to get the trait during object instantiation.
Code:
template <typename T, template <typename U> class backEndFactoryType = ClsBackEndTypeTraits >
class ClsSqlDataManager
{
public:
ClsSqlDataManager();
~ClsSqlDataManager();
int ReadData(const int&, const std::string&, soci::row&);
int WriteData(const int&, const std::string&, soci::row&);
//typedef backEndFactoryType<U>::backEndType backEndType;
};
template <class T>
class ClsBackEndTypeTraits
{
public:
typedef T backEndType;
};
//----------------------------------------------------------------
// Sqlite3 Back End Type Template Specialization
template <>
class ClsBackEndTypeTraits <soci::sqlite3_backend_factory>
{
public:
typedef soci::sqlite3_backend_factory backEndType;
};
Main.cpp
ClsSqlDataManager<Json::Value, ClsBackEndTypeTraits > db;
It cannot get the type traits defined.
Please help.
Thanks.
Re: Template Template Parameter and Template Traits
My Problem has been solved with this latest source code
Code:
template <typename T, class backEndFactoryType>
class ClsSqlDataManager
{
public:
ClsSqlDataManager();
~ClsSqlDataManager();
int ReadData(const int&, const std::string&, soci::row&);
int WriteData(const int&, const std::string&, soci::row&);
int ConvertToData(const T&);
int ConvertFromData(const T&);
void DataBinding();
public:
typedef typename ClsBackEndTypeTraits<backEndFactoryType>::backEndType databaseType;
template <class T>
class ClsBackEndTypeTraits
{
public:
typedef T backEndType;
};
//----------------------------------------------------------------
// Sqlite3 Back End Type Template Specialization
template <>
class ClsBackEndTypeTraits <soci::sqlite3_backend_factory>
{
public:
typedef soci::sqlite3_backend_factory backEndType;
};
ClsSqlDataManager<Json::Value, soci::sqlite3_backend_factory > db;
template <typename T, class backEndType>
int ClsSqlDataManager<T, backEndType>::ReadData(const int& dbType, const std::string& queryStr,
soci::row& rowResultSet)
{
// Error Here. Why compiler cannot resolve the type ?
soci::backend_factory& backEndFactory = ClsSqlDataManager<T, backEndType>::databaseType;
soci::backend_factory& backEndFactory = ClsBackEndTypeTraits<soci::sqlite3_backend_factory>::backEndType;
// Both statements are cannot resolve as a type.
}
But i found out that compiler cannot resolve the traits type once i used it.
Thanks.
Re: Template Template Parameter and Template Traits
Quote:
Originally Posted by
Peter_APIIT
My Problem has been solved with this latest source code
Code:
template <typename T, class backEndFactoryType>
class ClsSqlDataManager
{
public:
ClsSqlDataManager();
~ClsSqlDataManager();
int ReadData(const int&, const std::string&, soci::row&);
int WriteData(const int&, const std::string&, soci::row&);
int ConvertToData(const T&);
int ConvertFromData(const T&);
void DataBinding();
public:
typedef typename ClsBackEndTypeTraits<backEndFactoryType>::backEndType databaseType;
};
template <class T>
class ClsBackEndTypeTraits
{
public:
typedef T backEndType;
};
//----------------------------------------------------------------
// Sqlite3 Back End Type Template Specialization
template <>
class ClsBackEndTypeTraits <soci::sqlite3_backend_factory>
{
public:
typedef soci::sqlite3_backend_factory backEndType;
};
ClsSqlDataManager<Json::Value, soci::sqlite3_backend_factory > db;
template <typename T, class backEndType>
int ClsSqlDataManager<T, backEndType>::ReadData(const int& dbType, const std::string& queryStr,
soci::row& rowResultSet)
{
// Error Here. Why compiler cannot resolve the type ?
soci::backend_factory& backEndFactory = ClsSqlDataManager<T, backEndType>::databaseType;
soci::backend_factory& backEndFactory = ClsBackEndTypeTraits<soci::sqlite3_backend_factory>::backEndType;
// Both statements are cannot resolve as a type.
}
But i found out that compiler cannot resolve the traits type once i used it.
Thanks.
Any chance it's just this?
Also, this does not make sense to me:
Code:
soci::backend_factory& backEndFactory = ClsSqlDataManager<T, backEndType>::databaseType
how can you have a reference to a type? Perhaps this is what you meant?
Code:
soci::backend_factory backEndFactory = ClsSqlDataManager<T, backEndType>::databaseType()
Re: Template Template Parameter and Template Traits
Yes, that all i have change.
OK. I understand why.
Because my statement is assign a type to a variable rather than instantiate a type and assign to a variable.
This problem was solved but there is another problem.
But compiler complaints that soci::sqlite3_backend_factory is private.
Code:
soci::backend_factory const& backEnd = sqlite3;
This statement was working
but when i pass in the soci::sqlite3 statement into the trait class, compiler complaints that soci::sqlite3 is not a type.
Quote:
error: type/value mismatch at argument 1 in template parameter list for ‘template<class T> class ClsBackEndTypeTraits’
error: expected a type, got ‘soci::sqlite3’
and the source code for the header file is included below.
Code:
//
// Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton, David Courtney
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_SQLITE3_H_INCLUDED
#define SOCI_SQLITE3_H_INCLUDED
#ifdef _WIN32
# ifdef SOCI_DLL
# ifdef SOCI_SQLITE3_SOURCE
# define SOCI_SQLITE3_DECL __declspec(dllexport)
# else
# define SOCI_SQLITE3_DECL __declspec(dllimport)
# endif // SOCI_SQLITE3_SOURCE
# endif // SOCI_DLL
#endif // _WIN32
//
// If SOCI_SQLITE3_DECL isn't defined yet define it now
#ifndef SOCI_SQLITE3_DECL
# define SOCI_SQLITE3_DECL
#endif
#include <vector>
#include "soci-backend.h"
// Disable flood of nonsense warnings generated for SQLite
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4510 4610)
#endif
namespace sqlite_api
{
#include <sqlite3.h>
}
#undef SQLITE_STATIC
#define SQLITE_STATIC ((sqlite_api::sqlite3_destructor_type)0)
#ifdef _MSC_VER
#pragma warning(pop)
#endif
namespace soci
{
struct sqlite3_statement_backend;
struct sqlite3_standard_into_type_backend : details::standard_into_type_backend
{
sqlite3_standard_into_type_backend(sqlite3_statement_backend &st)
: statement_(st) {}
virtual void define_by_pos(int &position,
void *data, details::exchange_type type);
virtual void pre_fetch();
virtual void post_fetch(bool gotData, bool calledFromFetch,
indicator *ind);
virtual void clean_up();
sqlite3_statement_backend &statement_;
void *data_;
details::exchange_type type_;
int position_;
};
struct sqlite3_vector_into_type_backend : details::vector_into_type_backend
{
sqlite3_vector_into_type_backend(sqlite3_statement_backend &st)
: statement_(st) {}
virtual void define_by_pos(int &position,
void *data, details::exchange_type type);
virtual void pre_fetch();
virtual void post_fetch(bool gotData, indicator *ind);
virtual void resize(std::size_t sz);
virtual std::size_t size();
virtual void clean_up();
sqlite3_statement_backend &statement_;
void *data_;
details::exchange_type type_;
int position_;
};
struct sqlite3_standard_use_type_backend : details::standard_use_type_backend
{
sqlite3_standard_use_type_backend(sqlite3_statement_backend &st)
: statement_(st), buf_(0) {}
virtual void bind_by_pos(int &position,
void *data, details::exchange_type type, bool readOnly);
virtual void bind_by_name(std::string const &name,
void *data, details::exchange_type type, bool readOnly);
virtual void pre_use(indicator const *ind);
virtual void post_use(bool gotData, indicator *ind);
virtual void clean_up();
sqlite3_statement_backend &statement_;
void *data_;
details::exchange_type type_;
int position_;
std::string name_;
char *buf_;
};
struct sqlite3_vector_use_type_backend : details::vector_use_type_backend
{
sqlite3_vector_use_type_backend(sqlite3_statement_backend &st)
: statement_(st) {}
virtual void bind_by_pos(int &position,
void *data, details::exchange_type type);
virtual void bind_by_name(std::string const &name,
void *data, details::exchange_type type);
virtual void pre_use(indicator const *ind);
virtual std::size_t size();
virtual void clean_up();
sqlite3_statement_backend &statement_;
void *data_;
details::exchange_type type_;
int position_;
std::string name_;
};
struct sqlite3_column
{
std::string data_;
bool isNull_;
char * blobBuf_;
std::size_t blobSize_;
};
typedef std::vector<sqlite3_column> sqlite3_row;
typedef std::vector<sqlite3_row> sqlite3_recordset;
struct sqlite3_session_backend;
struct sqlite3_statement_backend : details::statement_backend
{
sqlite3_statement_backend(sqlite3_session_backend &session);
virtual void alloc();
virtual void clean_up();
virtual void prepare(std::string const &query,
details::statement_type eType);
void resetIfNeeded();
virtual exec_fetch_result execute(int number);
virtual exec_fetch_result fetch(int number);
virtual int get_number_of_rows();
virtual std::string rewrite_for_procedure_call(std::string const &query);
virtual int prepare_for_describe();
virtual void describe_column(int colNum, data_type &dtype,
std::string &columnName);
virtual sqlite3_standard_into_type_backend * make_into_type_backend();
virtual sqlite3_standard_use_type_backend * make_use_type_backend();
virtual sqlite3_vector_into_type_backend * make_vector_into_type_backend();
virtual sqlite3_vector_use_type_backend * make_vector_use_type_backend();
sqlite3_session_backend &session_;
sqlite_api::sqlite3_stmt *stmt_;
sqlite3_recordset dataCache_;
sqlite3_recordset useData_;
bool databaseReady_;
bool boundByName_;
bool boundByPos_;
private:
exec_fetch_result loadRS(int totalRows);
exec_fetch_result loadOne();
exec_fetch_result bindAndExecute(int number);
};
struct sqlite3_rowid_backend : details::rowid_backend
{
sqlite3_rowid_backend(sqlite3_session_backend &session);
~sqlite3_rowid_backend();
unsigned long value_;
};
struct sqlite3_blob_backend : details::blob_backend
{
sqlite3_blob_backend(sqlite3_session_backend &session);
~sqlite3_blob_backend();
virtual std::size_t get_len();
virtual std::size_t read(std::size_t offset, char *buf,
std::size_t toRead);
virtual std::size_t write(std::size_t offset, char const *buf,
std::size_t toWrite);
virtual std::size_t append(char const *buf, std::size_t toWrite);
virtual void trim(std::size_t newLen);
sqlite3_session_backend &session_;
std::size_t set_data(char const *buf, std::size_t toWrite);
private:
char *buf_;
size_t len_;
};
struct sqlite3_session_backend : details::session_backend
{
sqlite3_session_backend(std::string const &connectString);
~sqlite3_session_backend();
virtual void begin();
virtual void commit();
virtual void rollback();
virtual std::string get_backend_name() const { return "sqlite3"; }
void clean_up();
virtual sqlite3_statement_backend * make_statement_backend();
virtual sqlite3_rowid_backend * make_rowid_backend();
virtual sqlite3_blob_backend * make_blob_backend();
sqlite_api::sqlite3 *conn_;
};
struct sqlite3_backend_factory : backend_factory
{
virtual sqlite3_session_backend * make_session(
std::string const &connectString) const;
};
extern SOCI_SQLITE3_DECL sqlite3_backend_factory const sqlite3;
extern "C"
{
// for dynamic backend loading
SOCI_SQLITE3_DECL backend_factory const * factory_sqlite3();
} // extern "C"
} // namespace soci
#endif // SOCI_SQLITE3_H_INCLUDED
Please help.
Thanks.
Re: Template Template Parameter and Template Traits
Quote:
Originally Posted by
Peter_APIIT
Code:
soci::backend_factory const& backEnd = sqlite3;
This statement was working
but when i pass in the soci::sqlite3 statement into the trait class, compiler complaints that soci::sqlite3 is not a type.
soci::sqlite3 is an object, not a statement.
Pass into which traits class? How do you pass an object into a class? You can pass a type to a template class or you can pass an object to a function (possibly a constructor).
Quote:
Originally Posted by
Peter_APIIT
Please help.
Thanks.
I think you'll get a lot more help if you post a minimal but complete example that replicates your problem.