C++ 选择C++;基于成员类型可用性的模板专门化
我正在写一种序列化类。它必须为容器提供功能。目前的实施是:C++ 选择C++;基于成员类型可用性的模板专门化,c++,templates,C++,Templates,我正在写一种序列化类。它必须为容器提供功能。目前的实施是: template <typename InsertIter> bool readContainer(InsertIter result) { typedef typename InsertIter::container_type::value_type tVal; UInt32 size = 0; if (!read(size)) return false; for (UI
template <typename InsertIter>
bool readContainer(InsertIter result)
{
typedef typename InsertIter::container_type::value_type tVal;
UInt32 size = 0;
if (!read(size))
return false;
for (UInt32 i = 0; i < size; ++i)
{
tVal val;
if (!read(val))
return false;
*result++ = val;
}
return true;
}
template <typename InsertIter>
bool readMap(InsertIter result)
{
typedef typename InsertIter::container_type::key_type tKey;
typedef typename InsertIter::container_type::mapped_type tVal;
UInt32 size = 0;
if (!read(size))
return false;
for (UInt32 i = 0; i < size; ++i)
{
std::pair<tKey, tVal> pair;
if (!read(pair))
return false;
*result++ = pair;
}
return true;
}
模板
bool readContainer(插入器结果)
{
typedef typename插入器::容器类型::值类型tVal;
UInt32尺寸=0;
如果(!读取(大小))
返回false;
对于(UInt32 i=0;i
如您所见,我必须为map-like类型(std::map
)和其他容器创建不同的实现,因为std::map::value\u type
是std::pair(const K,V)
而不是std::pair(K,V)
因此,我想创建方法
read(插入器)
,它将自动选择合适的readContainer(插入器)
或readMap(插入器)
。这是可能的吗?我有一个例子做了一些非常类似的事情,它应该非常简单,您可以转换为您需要的东西:
#include <iostream>
template< typename T >
struct A;
template<>
struct A< int >
{
void foo() const
{
std::cout<<"A(int)::foo()"<<std::endl;
}
};
template<>
struct A< float >
{
void foo() const
{
std::cout<<"A(float)::foo()"<<std::endl;
}
};
template< typename T >
void call( const A<T> &a)
{
a.foo();
}
struct B
{
template<typename T>
void bar(const A<T> &a)
{
call(a);
}
};
int main()
{
A<int> a1;
A<float> a2;
B b;
b.bar(a1);
b.bar(a2);
}
#包括
模板
结构A;
样板
结构A
{
void foo()常量
{
我已经成功地解决了我的问题
多亏了约翰·伦德伯格,尤其是n.m.-我不熟悉这个成语,你们的链接和示例对我帮助很大
我不能使用C++11特性(项目细节),但它们不是必需的
当前代码如下所示:
struct SFINAE
{
typedef char __one;
typedef struct { char __arr[2]; } __two;
};
template <typename T>
class has_mapped_type : public SFINAE
{
template <typename C> static __one test(typename C::mapped_type *);
template <typename C> static __two test(...);
public:
enum { value = (sizeof(test<T>(0)) == sizeof(__one)) };
};
class Serializer
{
template <typename InsertIter>
bool read(InsertIter result) const
{
return readContainerSelector< InsertIter,
has_mapped_type<typename InsertIter::container_type>::value
> ::read(result, *this);
}
template <typename InsertIter, bool isMapType>
struct readContainerSelector;
template <typename InsertIter>
struct readContainerSelector<InsertIter, true>
{
static bool read(InsertIter result, Serializer const& ser)
{
return ser.readMap(result);
}
};
template <typename InsertIter>
struct readContainerSelector<InsertIter, false>
{
static bool read(InsertIter result, Serializer const& ser)
{
return ser.readContainer(result);
}
};
// methods from my topic post
template <typename InsertIter> bool readContainer(InsertIter result);
template <typename InsertIter> bool readMap(InsertIter result)
};
struct SFINAE
{
typedef char\uu one;
typedef结构{char uu arr[2];}uu二;
};
样板
类具有映射类型:public SFINAE
{
模板静态测试(typename C::mapped_type*);
模板静态二次试验(…);
公众:
枚举{value=(sizeof(test(0))==sizeof(uu one))};
};
类序列化程序
{
样板
布尔读取(插入器结果)常量
{
返回readContainerSelector<插入器,
已映射\u类型::值
>::读取(结果,*此);
}
样板
结构readContainerSelector;
样板
结构readContainerSelector
{
静态布尔读取(插入器结果、序列化器常量和序列号)
{
返回序列readMap(结果);
}
};
样板
结构readContainerSelector
{
静态布尔读取(插入器结果、序列化器常量和序列号)
{
返回序列号readContainer(结果);
}
};
//我的主题帖子中的方法
模板bool readContainer(插入器结果);
模板bool readMap(插入器结果)
};
看看这里,特别是看看这里。这显示了如何启用/禁用方法。可能的重复?看看代码。有有值类型和有键类型模板,您可以按原样使用std::enable\u if
选择正确的实现。