gpt4 book ai didi

c++ - 从可变参数模板中的扩展 decltype 继承

转载 作者:搜寻专家 更新时间:2023-10-31 01:30:07 33 4
gpt4 key购买 nike

我正在试验 C++ 模板元编程,试图创建一个具有以下语义的存储类:它采用任意数量的类型,并为每个类型存储一个用户定义类型的容器,具有公共(public)访问接口(interface)。我能够使用以下代码使用来自 decltype 扩展列表的多重继承来实现它( AB 只是要放入 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 列表继承是否合法(即符合标准)。所以,我的问题是:

  1. struct Storage: public decltype(componentContainer<Component>())...标准 C++ 中的合法事物还是 gcc 功能?
  2. 如果是,是否可以在 Visual Studio 中完成?

最佳答案

这在 MSVC 中对我有用。

template<typename T>
struct StorageBase
{
using Type = decltype(componentContainer<T>());
};

template<typename... Component>
struct Storage : public StorageBase<Component>::Type...
{ }

语法错误让我相信编译器在扩展参数包之前试图评估 decltype 表达式 - 因此它也发出 'Component': parameter pack must be在此上下文中展开

通过使用 StorageBase 来简化表达式,用 decltype 完成肮脏的工作看起来可以完成这项工作。

关于c++ - 从可变参数模板中的扩展 decltype 继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48554485/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com