我想创建一个类似于std :: iterator_traits :: value_type的构造,它可以使用相同的语法无缝地为所有类型工作。想象一下,我们有以下几点:
template <typename T>
struct value_type {
typedef T type;
};
#define VALUE_TYPE(T) typename value_type<T >::type
这适用于POD类型。我可以把它专门用于我自己的课程:
struct MyClass {
typedef float value_type;
};
template <>
struct value_type<MyClass> {
typedef MyClass::value_type type;
};
虽然我宁愿在理想世界中避免额外的value_type实例化。
问题在于STL迭代器。我需要一个特殊化,让我进入迭代器层次结构。这失败是因为编译器选择了基本情况:
template <>
struct value_type<std::_Iterator_base_aux> { // MSVC implementation
typedef value_type type;
};
选择层次结构中较高的类(_Iterator_with_base最自然,因为这是定义value_type的地方)失败,因为它需要将所有迭代器特征指定为模板参数。
我正在尝试用C ++做什么?
答案 0 :(得分:3)
您可以使用SFINAE检测是否存在value_type
typedef。无需专门针对个别类型(这可能是不可能的,因为您完全依赖于内部实现细节)。
#include <vector>
template <class T>
struct has_value_type
{
typedef char true_type;
typedef char false_type[2];
//template not available if there's no nested value_type in U's scope
template <class U>
static true_type test(typename U::value_type* );
//fallback
template <class U>
static false_type& test(...);
//tests which overload of test is chosen for T
static const bool value = sizeof(test<T>(0)) == sizeof(true_type);
};
template <class T, bool b>
struct value_type_impl;
template <class T>
struct value_type_impl<T, false> //if T doesn't define value_type
{
typedef T type;
};
template <class T>
struct value_type_impl<T, true> //if T defines value_type
{
typedef typename T::value_type type;
};
template <class T>
struct value_type: value_type_impl<T, has_value_type<T>::value>
{
};
struct MyClass {
typedef float value_type;
};
template <class T>
int foo(T )
{
return typename value_type<T>::type();
}
int main()
{
foo(MyClass());
std::vector<int> vec;
foo(vec.begin());
foo(10);
}
答案 1 :(得分:1)
UncleBens
使用了SFINAE,但实际上更简单:
template <class T>
struct value_type
{
typedef typename T::value_type type;
};
现在,如果您想将它与您控制的类一起使用,最简单的方法是:
struct MyClass { typedef float value_type; };
BOOST_MPL_ASSERT((boost::is_same< MyClass::value_type,
typename value_type<MyClass>::type >));
如果你想用于你无法控制的课程,你仍然有专业化:
struct ThirdPartyClass {};
template <>
struct value_type<ThirdPartyClass> { typedef int type; }
如果您尝试将value_type
用于没有内部typedef
且没有可用专业化的类,则会出现编译错误(以及您不太可能理解的消息)乍一看......)