我有一个代表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