Loki TypeTraits and compilation problems

Discussion in 'C++' started by Krivenok Dmitry, Sep 14, 2005.

  1. 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???
     
    Krivenok Dmitry, Sep 14, 2005
    #1
    1. Advertising

  2. Krivenok Dmitry

    mlimber Guest

    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/WG21/docs/papers/2005/n1745.pdf).

    Cheers! --M
     
    mlimber, Sep 14, 2005
    #2
    1. Advertising

  3. 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 (*)
     
    Krivenok Dmitry, Sep 14, 2005
    #3
  4. Krivenok Dmitry

    mlimber Guest

    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
     
    mlimber, Sep 14, 2005
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Sebastian Faust

    Loki::Factory and Loki::TList

    Sebastian Faust, Oct 30, 2003, in forum: C++
    Replies:
    0
    Views:
    687
    Sebastian Faust
    Oct 30, 2003
  2. Replies:
    1
    Views:
    451
    Phil Staite
    Dec 25, 2004
  3. Pep
    Replies:
    2
    Views:
    428
  4. Kalle Rutanen

    Loki TypeTraits bugs

    Kalle Rutanen, Aug 21, 2005, in forum: C++
    Replies:
    1
    Views:
    368
    Kalle Rutanen
    Aug 23, 2005
  5. laikon
    Replies:
    6
    Views:
    775
    Michael Doubez
    Sep 22, 2009
Loading...

Share This Page