Define a character in another namespace

Here is my problem: in the header, I define a structure template type_to_stringthat aims to define a string that matches a given type argument:

namespace foo {

    template <typename T>
    struct type_to_string
    {
        static const char * value;
    };
}

template <typename T>
const char * foo::type_to_string<T>::value = "???";

I also define the default value for the string.

Now I want to use a macro to define new types:

#define CREATE_ID(name)                               \
struct name;                                          \
                                                      \
template<>                                            \
const char * foo::type_to_string<name>::value = #name;

The problem is that I would like to use a macro in namespaces, for example:

namespace bar
{
    CREATE_ID(baz)
}

which is impossible because it type_to_string<T>::valueneeds to be defined in the namespace spanning foo.

Here are the compilation errors that I get:

[COMEAU 4.3.10.1] error: member "foo::type_to_string<T>::value [with T=bar::baz]"
cannot be specialized in the current scope

[VISUAL C++ 2008] error C2888: 'const char *foo::type_to_string<T>::value' :
symbol cannot be defined within namespace 'bar'
     with
     [
         T=bar::baz
     ]

Oddly enough, GCC 4.3.5 (MinGW version) does not cause errors.

- , , , (.. type_to_string , - )?

+3
2

++ 14.7.3/2:

, , -, , . -, - , . . , name- , ​​ , , , ​​ .

:

#define DECL_ID(name) \
struct name;                                          

#define CREATE_ID(name) \
template<>              \
const char * foo::type_to_string<name>::value = #name;

namespace bar { namespace bar2 {
    DECL_ID(baz)
} }
CREATE_ID(bar::bar2::baz)

#define CREATE_ID(ns, name)     \
namespace ns { struct name; }   \
                                \
template<>                      \
const char * foo::type_to_string<ns::name>::value = #name;

CREATE_ID(bar, baz)

- . value ( ):

#define DECL_ID(name) \
struct name;                                          

#define CREATE_ID(ns, name) \
template<>              \
const char * foo::type_to_string<ns::name>::value = #name;

namespace bar { namespace bar2 {
    DECL_ID(baz)
} }
CREATE_ID(bar::bar2, baz)
+9

, , Boost.Preprocessor:

#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/seq/size.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>

#define BEGIN_NS(r, _, elem)  namespace elem {
#define CLOSE_NS(z, n, _)     }
#define APPEND_NS(r, _, elem) elem::

#define CREATE_ID(ns_list, name)                         \
                                                         \
BOOST_PP_SEQ_FOR_EACH(BEGIN_NS, ~, ns_list)              \
    struct name;                                         \
BOOST_PP_REPEAT(BOOST_PP_SEQ_SIZE(ns_list), CLOSE_NS, ~) \
                                                         \
template<>                                               \
const char * devs::type_to_string<                       \
    BOOST_PP_SEQ_FOR_EACH(APPEND_NS, ~, ns_list)name     \
>::value = #name;

, :

CREATE_ID((bar) (bar2), baz)

, n '}', - , !

+1

Source: https://habr.com/ru/post/1718445/


All Articles