By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,951 Members | 1,039 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,951 IT Pros & Developers. It's quick & easy.

Loki TypeTraits and compilation problems

P: n/a
I writing simple class CmdLine:
.....
.....
class CmdLine
{
.....
.....
public:
/// Constructor
CmdLine(int argc, char** argv);
/// Destructor
~CmdLine();

template <class T>
void GetOption (const std::string& OptionName, T& OptionVar) const
{
if ( Loki::TypeTraits<T>::isStdIntegral )
{
std::cout << "bool\n"; //For debug
OptionVar = BoolOptions_.find(OptionName)->second;
}
else
{
std::cout << "string\n"; //for debug
OptionVar = StringOptions_.find(OptionName)->second;
}
}
private:
/// Map for string options, e.g. Script File Name
std::map<std::string,std::string> StringOptions_;
/// Map for bool options, e.g. Disable StdErr Output
std::map<std::string,bool> BoolOptions_;
....
....
};
.....
.....

I use TypeTraits from Loki Library by A. Alexandrescu to determine
types class (integral or not).
If type is integral (e.g. bool), then I use BoolOptions_ map. Else
I use StringOptions_ map.

My main function :
#include <string>
#include <iostream>
#include "Cmdline.hpp"
#include "Cfg.h"

using namespace std;

int main( int argc, char* argv[] )
{
CmdLine CC(argc,argv);
bool b;
std::string s;
CC.GetOption("str_opt",s);
CC.GetOption("bool_opt",b);
return 0;
}

But my code doesn't compile!
Errors are :

CmdLineParse/Cmdline.hpp: In member function `void
CmdLine::GetOption(const
std::string&, T&) const [with T = bool]':
Application/Application.cpp:20: instantiated from here
CmdLineParse/Cmdline.hpp:52: cannot convert `const std::string' to
`bool' in
assignment

But if I comment assigments (OptionVar = ...), then my code compile
succ
and output is:
string
bool

In this case used valid branch of 'if' statment.

Why my code doesn't compile if first case???

Sep 14 '05 #1
Share this Question
Share on Google+
3 Replies


P: n/a
Krivenok Dmitry wrote:
I writing simple class CmdLine:
....
....
class CmdLine
{
.....
.....
public:
/// Constructor
CmdLine(int argc, char** argv);
/// Destructor
~CmdLine();

template <class T>
void GetOption (const std::string& OptionName, T& OptionVar) const
{
if ( Loki::TypeTraits<T>::isStdIntegral )
{
std::cout << "bool\n"; //For debug
OptionVar = BoolOptions_.find(OptionName)->second;
}
else
{
std::cout << "string\n"; //for debug
OptionVar = StringOptions_.find(OptionName)->second;
}
}
private:
/// Map for string options, e.g. Script File Name
std::map<std::string,std::string> StringOptions_;
/// Map for bool options, e.g. Disable StdErr Output
std::map<std::string,bool> BoolOptions_;
....
....
};
....
....

I use TypeTraits from Loki Library by A. Alexandrescu to determine
types class (integral or not).
If type is integral (e.g. bool), then I use BoolOptions_ map. Else
I use StringOptions_ map.

My main function :
#include <string>
#include <iostream>
#include "Cmdline.hpp"
#include "Cfg.h"

using namespace std;

int main( int argc, char* argv[] )
{
CmdLine CC(argc,argv);
bool b;
std::string s;
CC.GetOption("str_opt",s);
CC.GetOption("bool_opt",b);
return 0;
}

But my code doesn't compile!
Errors are :

CmdLineParse/Cmdline.hpp: In member function `void
CmdLine::GetOption(const
std::string&, T&) const [with T = bool]':
Application/Application.cpp:20: instantiated from here
CmdLineParse/Cmdline.hpp:52: cannot convert `const std::string' to
`bool' in
assignment

But if I comment assigments (OptionVar = ...), then my code compile
succ
and output is:
string
bool

In this case used valid branch of 'if' statment.

Why my code doesn't compile if first case???


It's because your function CmdLine::GetOption<>() is instantiated for a
type T (in this case either bool or std::string), but one of the two
assignments won't compile for T. That is, for T=bool your function is
instantiated as:

void GetOption (const std::string& OptionName, bool& OptionVar) const
{
if ( Loki::TypeTraits<T>::isStdIntegral )
{
std::cout << "bool\n"; //For debug
OptionVar = BoolOptions_.find(OptionName)->second;
// Ok: that's bool = bool.
}
else
{
std::cout << "string\n"; //for debug
OptionVar = StringOptions_.find(OptionName)->second;
// Error: that's bool = std::string!
}
}

And likewise for T=std::string. You could use partial template
specialization to do what you want:

template<typename T>
void GetOption( std::string const& OptionName, T& OptionVar ) const;

template<>
void CmdLine::GetOption<std::string>(
std::string const& OptionName,
std::string & OptionVar ) const
{
std::cout << "string\n"; //for debug
OptionVar = StringOptions_.find(OptionName)->second;
}

template<>
void CmdLine::GetOption<bool>(
std::string const& OptionName,
bool& OptionVar ) const
{
std::cout << "bool\n"; //For debug
OptionVar = BoolOptions_.find(OptionName)->second;
}

Also, you may want to consider using Boost's type traits instead of
Loki's. They do essentially the same task, but the former is more
widely tested and are part of TR1, which will likely become part of the
C++ standard library soon (see
http://www.open-std.org/JTC1/SC22/WG...005/n1745.pdf).

Cheers! --M

Sep 14 '05 #2

P: n/a
I read Modern C++ Design (2.10.5)
and write this code:

enum MapSelector {Integral, String};

template <class T>
void GetOptionImpl (const std::string& OptionName, T&
OptionVar,Loki::Int2Type<Integral>) const
{
std::cout << "bool\n";
OptionVar = BoolOptions_.find(OptionName)->second;
}

template <class T>
void GetOptionImpl (const std::string& OptionName, T&
OptionVar,Loki::Int2Type<String>) const
{
std::cout << "string\n";
OptionVar = StringOptions_.find(OptionName)->second;
}

template <class T>
void GetOption (const std::string& OptionName, T& OptionVar) const
{
enum {MapType = Loki::TypeTraits<T>::isStdIntegral ? Integral :
String };
// Problem line (*)
GetOptionImpl(OptionName, OptionVar, Loki::Int2Type<MapType>);
}

But compilation is not succ again!
Errors are:
In file included from CmdLineParse/Cmdline.cpp:7:
CmdLineParse/Cmdline.hpp: In member function `void
CmdLine::GetOption(const
std::string&, T&) const':
CmdLineParse/Cmdline.hpp:59: syntax error before `;' token

Line 59 = Problem line (*)

Sep 14 '05 #3

P: n/a

Krivenok Dmitry wrote:
I read Modern C++ Design (2.10.5)
and write this code:

enum MapSelector {Integral, String};

template <class T>
void GetOptionImpl (const std::string& OptionName, T&
OptionVar,Loki::Int2Type<Integral>) const
{
std::cout << "bool\n";
OptionVar = BoolOptions_.find(OptionName)->second;
}

template <class T>
void GetOptionImpl (const std::string& OptionName, T&
OptionVar,Loki::Int2Type<String>) const
{
std::cout << "string\n";
OptionVar = StringOptions_.find(OptionName)->second;
}

template <class T>
void GetOption (const std::string& OptionName, T& OptionVar) const
{
enum {MapType = Loki::TypeTraits<T>::isStdIntegral ? Integral :
String };
// Problem line (*)
GetOptionImpl(OptionName, OptionVar, Loki::Int2Type<MapType>);
}

But compilation is not succ again!
Errors are:
In file included from CmdLineParse/Cmdline.cpp:7:
CmdLineParse/Cmdline.hpp: In member function `void
CmdLine::GetOption(const
std::string&, T&) const':
CmdLineParse/Cmdline.hpp:59: syntax error before `;' token

Line 59 = Problem line (*)


See my previous post for an alternate solution that is easier to read
IMHO, but I think you need to create an Int2Type<> object on your
problem line:

GetOptionImpl(OptionName, OptionVar, Loki::Int2Type<MapType>() );

Cheers! --M

Sep 14 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.