VS 2013, operator<< для вложенного класса-потомка включающего класса
От: godplayer  
Дата: 08.12.14 09:04
Оценка:
Всем привет. Есть такой код (nested.cpp):

#include <iostream>
#include <string>
#include <sstream>

class base_exception
{
public:
    template <class E> friend E const& operator<<(E const& ex, std::string const& str)
    {
        ex.m_what += str;
        return ex;
    }
    std::string const& what() const
    {
        return m_what;
    }
private:
    mutable std::string m_what;
};

class module_error : public base_exception
{
public:
    class bad_config;
};

class module_error::bad_config : public module_error
{
};

int main()
{    
    module_error::bad_config err;
    err << "module_error::bad_config" << " test"; // строка 34
    std::cout << err.what() << std::endl;
    return 0;
}


На gcc 4.6.2 всё работает, Visual Studio 12 2013 выдает ошибку компиляции:
Microsoft (R) Build Engine version 12.0.21005.1
[Microsoft .NET Framework, version 4.0.30319.18444]
...
nested.cpp(34): error C2676: binary '<<' : 'module_error::bad_config' does not define this operator or a conversion to a type acceptable to the predefined operator

Можно ли это как-то побороть?
Re: VS 2013, operator<< для вложенного класса-потомка включающего класса
От: frymode  
Дата: 08.12.14 09:37
Оценка: 1 (1)
Здравствуйте, godplayer, Вы писали:

G>nested.cpp(34): error C2676: binary '<<' : 'module_error::bad_config' does not define this operator or a conversion to a type acceptable to the predefined operator

G>Можно ли это как-то побороть?

Вроде бы по стандарту необходимо реализовывать свободную функцию вне класса:

class base_exception
{
public:
    template <class E> friend E const& operator<<(E const& ex, std::string const& str);
    ...
private:
    mutable std::string m_what;
};

template <class E> E const& operator<<(E const& ex, std::string const& str)
{
    ex.m_what += str;
    return ex;
}
Re: VS 2013, operator<< для вложенного класса-потомка включа
От: andyp  
Дата: 08.12.14 09:39
Оценка:
Здравствуйте, godplayer, Вы писали:

G>Всем привет. Есть такой код (nested.cpp):


G>[ccode]

G>#include <iostream>
G>#include <string>
G>#include <sstream>

G>Можно ли это как-то побороть?


Сделать operator<<() членом класса base_exception?

class base_exception { 
public: 
    base_exception const& operator<<(std::string const& str) const
    { ex.m_what += str; return *this; } 
    std::string const& what() const { return m_what; } 
private: 
    mutable std::string m_what; 
};
Отредактировано 08.12.2014 9:43 andyp . Предыдущая версия .
Re[2]: VS 2013, operator<< для вложенного класса-потомка включающего класса
От: godplayer  
Дата: 09.12.14 09:15
Оценка:
Здравствуйте, frymode, Вы писали:

F>Здравствуйте, godplayer, Вы писали:


G>>nested.cpp(34): error C2676: binary '<<' : 'module_error::bad_config' does not define this operator or a conversion to a type acceptable to the predefined operator

G>>Можно ли это как-то побороть?

F>Вроде бы по стандарту необходимо реализовывать свободную функцию вне класса:


F>
F>class base_exception
F>{
F>public:
F>    template <class E> friend E const& operator<<(E const& ex, std::string const& str);
F>    ...
F>private:
F>    mutable std::string m_what;
F>};

F>template <class E> E const& operator<<(E const& ex, std::string const& str)
F>{
F>    ex.m_what += str;
F>    return ex;
F>}
F>


Спасибо, frymode, помогло!
Re[2]: VS 2013, operator<< для вложенного класса-потомка включа
От: godplayer  
Дата: 09.12.14 09:28
Оценка:
Здравствуйте, andyp, Вы писали:

A>Здравствуйте, godplayer, Вы писали:


G>>Всем привет. Есть такой код (nested.cpp):


G>>[ccode]

G>>#include <iostream>
G>>#include <string>
G>>#include <sstream>

G>>Можно ли это как-то побороть?


A>Сделать operator<<() членом класса base_exception?


A>
A>class base_exception { 
A>public: 
A>    base_exception const& operator<<(std::string const& str) const
A>    { ex.m_what += str; return *this; } 
A>    std::string const& what() const { return m_what; } 
A>private: 
A>    mutable std::string m_what; 
A>};
A>


Да, была такая мысль, но я планировал ловить конкретные исключения-потомки base_exception:
try
{
    ...
    if (!module.IsTimeConfigGood())
    {
        throw (module_error::bad_config() << "bad module time config");
    }
}
catch (const module_error::bad_config& err)
{
    ...
}
Re[3]: VS 2013, operator<< для вложенного класса-потомка включа
От: andyp  
Дата: 09.12.14 10:17
Оценка:
Здравствуйте, godplayer, Вы писали:

G>Да, была такая мысль, но я планировал ловить конкретные исключения-потомки base_exception:

G>
G>try
G>{
G>    ...
G>    if (!module.IsTimeConfigGood())
G>    {
G>        throw (module_error::bad_config() << "bad module time config");
G>    }
G>}
G>catch (const module_error::bad_config& err)
G>{
G>    ...
G>}
G>


Да, так будет кидать ссылку на базовый класс.
Re[2]: VS 2013, operator<< для вложенного класса-потомка включающего класса
От: andyp  
Дата: 09.12.14 10:32
Оценка: 1 (1)
Здравствуйте, frymode, Вы писали:

F>Вроде бы по стандарту необходимо реализовывать свободную функцию вне класса:


Такой необходимости нет. Это особенность msvc-шного adl.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.