代码之家  ›  专栏  ›  技术社区  ›  Luc Touraille

在另一个命名空间中定义符号

  •  3
  • Luc Touraille  · 技术社区  · 16 年前

    type_to_string

    namespace foo {
    
        template <typename T>
        struct type_to_string
        {
            static const char * value;
        };
    }
    
    template <typename T>
    const char * foo::type_to_string<T>::value = "???";
    

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

    namespace bar
    {
        CREATE_ID(baz)
    }
    

    type_to_string<T>::value 必须在封闭的命名空间中定义 foo .

    [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
         ]
    

    在宏中,每个名称空间都有自己的版本,或者类似的东西)?

    2 回复  |  直到 16 年前
        1
  •  9
  •   Kirill V. Lyadvinsky    16 年前

    根据C++标准14.7.3/2:

    #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)
    
        2
  •  1
  •   Luc Touraille    16 年前

    #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)