从可变模板创建实例

Create instances from variadic templates

本文关键字:创建 实例      更新时间:2023-10-16

我试图想出一个允许通过可变模板参数创建多种类型的类,但我在编译期间得到错误:

http://ideone.com/nDWBET

#include <list>
#include <memory>
struct IBaseType
{
};
class Type1 : public IBaseType
{
};
class Type2 : public IBaseType
{
};
template <typename... T>
class CreateTypes
{
public:
    CreateTypes()
    {
        [](...){ }((m_types.push_back(std::unique_ptr<T>(new T())))...);
    }
private:
    std::list<std::unique_ptr<IBaseType>> m_types;
};
int main()
{
    CreateTypes<Type1, Type2> createTypes;
    return 0;
}

prog.cpp: In instance of ' CreateTypes::CreateTypes() [with T = {Type1, Type2}] ':
Prog.cpp:31:28: required from here
Prog.cpp:22:9:错误:无效使用void表达式

这个问题的解决方案是什么?或者我可以采取其他方法?

这里的问题是,push_back返回void。您可以尝试使用insert

[](...) { }((m_types.insert(m_types.end(), std::unique_ptr<T>(new T())), 0)...);
从评论

:push_back = 0也可以。

[](...) { }((m_types.push_back(std::unique_ptr<T>(new T())), 0)...);

ForEveR和Xeo给了我我一直在寻找的答案,但我不得不稍微调整他们的解决方案,因为Clang不会执行空lambda的代码(我假设它被优化了,即使在调试中)。下面是我的最终解决方案(它包含了一个运行时检查,以确保总是创建正确数量的类型):

template <typename... Types>
struct VariadicTemplateCount
{
    static const size_t value = sizeof...(Types);
};
// ..............
CreateTypes()
{
    struct ShutTheCompiler
    {
        static void Up(const int[])
        {
        }
    };
    const int creation[] = {0, (m_types.push_back(std::unique_ptr<T>(new T())), 0)... };
    ShutTheCompiler::Up(creation);
    ASSERT(m_types.size() == VariadicTemplateCount<Types...>::value);
}