【发布时间】:2018-02-01 02:32:40
【问题描述】:
我正在尝试使用 C++ 模板元编程来尝试创建具有以下语义的存储类:它采用任意数量的类型并为每个具有通用访问接口的用户定义类型存储一个容器。我能够使用来自 decltype 扩展列表的多重继承通过以下代码实现它(A 和 B 只是要放入 Storage 的虚拟结构):
#include <iostream>
#include <string>
#include <map>
#include <unordered_map>
struct A
{
int v = -1;
};
struct B
{
std::string v;
};
typedef int Key;
template<typename T>
auto componentContainer();
template<>
auto componentContainer<A>()
{
return std::unordered_map<Key, A>();
}
template<>
auto componentContainer<B>()
{
return std::map<Key, B>();
}
template<typename... Component>
struct Storage : public decltype(componentContainer<Component>())...
{
template <typename T>
using Container = decltype(componentContainer<T>());
template<typename T>
T& get(int index)
{
return Container<T>::operator [](index);
}
template<typename T>
const T& get(int index) const
{
return Container<T>::operator [](index);
}
template<typename T>
void put(int index, const T& v)
{
Container<T>::operator [](index) = v;
}
template<typename T, typename F>
void apply(F f)
{
for (auto p = Container<T>::begin();
p != Container<T>::end();
p++)
{
f(p);
}
}
};
int main(int argc, char** argv)
{
Storage<A,B> s;
s.put<A>(0, {12});
s.put<A>(3, {42});
s.put<B>(0, {"melta"});
s.put<B>(42, {"multimelta"});
auto printer = [](auto p) { std::cout <<p->first <<": " << p->second.v <<std::endl;};
s.apply<A>(printer);
s.apply<B>(printer);
return 0;
}
此代码在 gcc 5.1.0 中编译得很好并产生了预期的结果,但在 Visual Studio 2015 中编译失败并出现以下错误消息:
main.cpp(37): error C2143: syntax error: missing ',' before '...'
main.cpp(70): note: see reference to class template instantiation 'Storage<Component...>' being compiled
main.cpp(37): error C3520: 'Component': parameter pack must be expanded in this context
main.cpp(74): note: see reference to class template instantiation 'Storage<A,B>' being compiled
main.cpp(37): error C3770: 'unknown-type': is not a valid base class
问题是,我不确定从这样的扩展 decltype 列表继承是否合法(即符合标准)。所以,我的问题是:
-
struct Storage: public decltype(componentContainer<Component>())...在标准 C++ 中是合法的还是 gcc 功能? - 如果是,可以在 Visual Studio 中完成吗?
【问题讨论】:
标签: c++ visual-studio gcc variadic-templates