October 20th, 2010 05:32 AM
#1
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.
Last edited by Peter_APIIT; October 20th, 2010 at 05:38 AM .
Thanks for your help.
October 20th, 2010 05:57 AM
#2
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.
Last edited by Peter_APIIT; October 20th, 2010 at 06:11 AM .
Thanks for your help.
October 20th, 2010 06:41 AM
#3
Re: Template Template Parameter and Template Traits
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()
Last edited by monarch_dodra; October 20th, 2010 at 06:47 AM .
Is your question related to IO?
Read this C++ FAQ LITE article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
October 21st, 2010 02:25 AM
#4
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.
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.
Last edited by Peter_APIIT; October 21st, 2010 at 03:52 AM .
Thanks for your help.
October 21st, 2010 07:07 AM
#5
Re: Template Template Parameter and Template Traits
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).
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.
Cheers, D Drmmr
Please put [code][/code]
tags around your code to preserve indentation and make it more readable.
As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky
Posting Permissions
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
Forum Rules
Click Here to Expand Forum to Full Width
Bookmarks