Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 选择C++;基于成员类型可用性的模板专门化_C++_Templates - Fatal编程技术网

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
选择正确的实现。