模板化模板参数方法的decltype

时间:2016-08-01 08:46:39

标签: c++ templates

我有一个代表TimeSeries of Data的类,因为我确实希望尽可能地保持内存效率,我模仿了类,因此存储的数据只会根据需要大小。但是现在我不能用不同的Base-Type来处理数据,所以我创建了一个基类,它具有我实际类的所有方法的虚拟版本。这种方法很好,直到出现了对虚拟模板方法的需求。 我可以用类型列表解决这个问题,但后来我需要一个带有动态返回类型的虚拟模板方法。我没有实现这一点。我做了一个" minimal"显示案例我的问题的例子。对我来说,似乎问题可以追溯到std :: result_of_t模板中的decltype语句,因为我的编译器指出:

error C2893: Failed to specialize function template 'enable_if<_Test,_Ty>::type Base::analyze(CtorArgs...)'
1>          with
1>          [
1>              _Ty=result_of<unknown-type(const std::vector<TList::Head,std::allocator<TList::Head>> &,CtorArgs...)>::type
1>          ]

这个错误在列表中相当远,但似乎是我唯一的解释。 这是代码:

#include <vector>
#include <iostream>
#include <type_traits>

template<typename T>
class TestAnalyzer
{
public:
    int analyze(const std::vector<T> &in, int a) { return a; }
};

//---------------------------------------------------------------------------------------
//Typelist stuff, only in here so it compiles, but im 99% sure, this is not the problem
class null_type {};

template<typename H, typename T>
struct TypelistNode
{
    using Head = H;
    using Tail = T;
};

template<typename Head, typename ...Tail>
struct make_typelist
{
    using type = TypelistNode<
        Head,
        typename make_typelist<Tail...>::type
    >;
};

template<typename Last>
struct make_typelist<Last>
{
    using type = TypelistNode<Last, null_type>;
};

template<typename ... Types>
using Typelist = typename make_typelist<Types...>::type;

using SupportedTypes = Typelist<
    uint8_t, int8_t,
    uint16_t, int16_t,
    uint32_t, int32_t,
    uint64_t, int64_t,
    float, double>;
//---------------------------------------------------------------------

class Base
{
public:
    //a few virtual methods here ...
    virtual ~Base() {}

    template<template <typename ...> class Analyzer, typename TList = SupportedTypes, typename ...CtorArgs>
    inline auto Base::analyze(CtorArgs ...)
        ->std::enable_if_t<!std::is_same<TList, null_type>::value,
        std::result_of_t<decltype(&Analyzer<typename TList::Head>::analyze)(const std::vector<typename TList::Head>&, CtorArgs ...)>
        >;

    template<
        template<typename T> class Analyzer,
        typename TList = SupportedTypes,
        typename ...CtorArgs>
        auto analyze(CtorArgs ...)
        ->std::enable_if_t<
        std::is_same<TList, null_type>::value,
        void>
    {
        throw std::logic_error("analyze was called with null_type");
    }
};

template <class T>
class Derived : public Base
{
public:
    //implementations of virtuals here

    template<template<typename T> class Analyzer, typename ...Args>
    std::result_of_t<decltype(&Analyzer<T>::analyze)(Args...)>
        analyze(Args... args)
    {
        Analyzer<T> a;
        return a.apply(_data, args...);
    }

private:
    std::vector<T> _data;
};

template<template <typename ...> class Analyzer, typename TList, typename ...CtorArgs>
inline auto Base::analyze(CtorArgs ... args)
-> std::enable_if_t<!std::is_same<TList, null_type>::value,
    std::result_of_t<decltype(&Analyzer<typename TList::Head>::analyze)(const std::vector<typename TList::Head>&, CtorArgs ...)>
>
{
    if (auto *ptr = dynamic_cast<Derived<typename TList::Head>*>(this))
    {
        return ptr->analyze<Analyzer>(args...);
    }
    else
        return analyze<Analyzer, typename TList::Tail, CtorArgs ...>(args...);
}

int main(int, char**)
{
    Derived<int> MyObj;
    Base *ptr = &MyObj;
    std::cout << ptr->analyze<TestAnalyzer>(1);
    return 0;
}

所以现在的问题是:我需要做些什么才能进行编译。

PS:我使用VS2015

0 个答案:

没有答案