我想知道是否有办法“重置”命名空间。我问这个主要是因为我想使用定义在另一个命名空间中专门化一些模板结构。
这是我可能想要实现的目标的简化示例:
namespace base {
template<typename>
struct my_traits;
}
// specialize base::my_traits for TYPE
// obviously, this does not work
#define MAKE_SPECIALIZED_TRAITS(TYPE) \
namespace ::base { \
template<> \
struct my_traits<TYPE> { \
typedef TYPE type; \
enum { size = TYPE::size }; \
}; \
}
namespace spec {
struct my_struct {
enum { size = 3 };
};
MAKE_SPECIALIZED_TRAITS(my_struct)
}
这样的事可能吗?如果是这样,我将如何实现?
最佳答案
一种有趣的技术,可以使用重写和 ADL 来生成特征类。
这是伪代码,但它可能是这样的:
namespace base {
// a template function you override in your OWN namespace to use this trick:
template<typename T>
void my_traits_mapping( T const& ) {};
// SFINAE enabled internal my_traits. if you have default traits, put them here:
template<typename T, typename=void>
struct my_traits_impl;
// Detect if my_traits_mapping has been overriden for T, and if so inherit
// my_traits_impl from its return value:
template<typename T>
struct my_traits_impl< T, typename std::enable_if< !std::is_same<
void, decltype( my_traits_mapping( std::declval<T>() ) )
>::value >::type >:
decltype( my_traits_mapping( std::declval<T&>() ) )
{};
// you might want to put the above in its own sub-namespace, so as not to clutter
// up your interface... if it is in details or aux, people will be less tempted to
// directly mess with it.
// forward my_traits<T> to the impl type above.
template<typename T>
struct my_traits : my_traits_impl<T> {};
}
我在 T
上使用 ADL调用my_traits_mapping
实例为 T
,提取返回类型,并继承my_traits_impl
来自它(只要它不是 void
)。
现在,不再专门my_traits
,您所要做的就是创建一个函数 my_traits_mapping(X)
它会在您自己的命名空间中返回一个特征类。当 my_traits<T>
求值,找到这个函数,找到返回值,用它的类型构建my_traits<T>
.
什么都没有离开你的namespace
,但是你神奇地将你的类型注入(inject)到特征系统中,没有向特征中注入(inject)任何东西 namespace
.
摆脱namespace
和template
你的宏中的东西。相反,创建一个 my_traits_FOO
输入 details
命名空间,然后添加 details::my_traits_FOO my_traits_mapping( FOO const& )
到您调用宏的命名空间,该命名空间应该与 FOO
相同的命名空间声明于。
关于c++ - #define 中暂时使用 'reset' 命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17155814/