从可变参数模板创建实例

时间:2013-06-07 10:22:53

标签: c++ templates c++11 variadic-templates

我正在尝试提出一个允许通过可变参数模板参数创建多个类型的类,但是在编译期间出现错误:

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:实例化'CreateTypes :: CreateTypes()[with T = {Type1,Type2}]':
  prog.cpp:31:28:从这里要求
  prog.cpp:22:9:错误:无效使用void表达式

这是什么解决方案?或者我可以选择其他方法吗?

2 个答案:

答案 0 :(得分:1)

问题在于,push_back返回void。您可以尝试使用insert

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

来自评论: 使用0 push_back也可以。

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

答案 1 :(得分: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);
}