C++ 解包元组可变模板参数

C++ 解包元组可变模板参数,c++,C++,我想解包一个可变类型的元组,并将参数转发到正确的类 class IntegerField(){ public: IntegerField(int i){} }; class StringField(){ public: StringField(std::string s){} }; class Person{ public: IntegerField id(){ return mId; } StringField name() { return m

我想解包一个可变类型的元组,并将参数转发到正确的类

class IntegerField(){
  public:
    IntegerField(int i){}
};
class StringField(){
   public:
      StringField(std::string s){}
};
class Person{
 public:
    IntegerField id(){ return mId; }
    StringField name() { return mName; }
 private:
  IntegerField mId;
  StringField mName;
};

template<typename... Types>
  void createField(Types... args){
     // want to create IntegerField or StringField and pass the args "42" or "Joe" respectively
     // exand the line to something like
     // std::make_unique<IntegerField>(42) 
     // ...
     auto uPtr = std::make_unique<Types...>(std::forward<Types...>(args)...);  // # ???
}

int main(){
   using IF = std::tuple<IntegerField, int>;
   using SF = std::tuple<StringField, std::string>;

   Person person;

   createField<IF, SF>({person.id(), 42},{person.name(), "Joe"});
}
class IntegerField(){
公众:
整数域(int i){}
};
类StringField(){
公众:
StringField(std::string s){}
};
班主任{
公众:
IntegerField id(){return mId;}
StringField name(){return mName;}
私人:
积分场;
StringField mName;
};
模板
void createField(类型…参数){
//要创建IntegerField或StringField并分别传递参数“42”或“Joe”
//把这条线改成
//标准::使_独一无二(42)
// ...
自动uPtr=std::使_唯一(std::转发(args);/#???
}
int main(){
使用IF=std::tuple;
使用SF=std::tuple;
个人;
createField({person.id(),42},{person.name(),“Joe”});
}

主要基于@arnes的工作:

#include <memory>
#include <type_traits>
#include <tuple>
#include <utility> // For std::index_sequence_for

class IntegerField{
  public:
    IntegerField(int i){}
};
class StringField{
   public:
      StringField(std::string s){}
};
class Person{
 public:
    Person() : mId { 5 } , mName { "empty" } {}
    IntegerField id(){ return mId; }
    StringField name() { return mName; }
 private:
    IntegerField mId;
    StringField mName;
};

namespace detail {
    template<class Field, class... Args, std::size_t... Indices>
    auto create(const std::tuple<Field, Args...>& t, std::index_sequence<Indices...> seq) {
        return std::make_unique<Field>(std::get<Indices + 1>(t)...);
    }
}

template<class Field, class... Args>
auto create(const std::tuple<Field, Args...>& t) -> std::enable_if_t<std::is_constructible_v<Field, Args...>, std::unique_ptr<Field>> {
    return detail::create(t, std::index_sequence_for<Args...>{});
}


template<typename... Types>
void createField(Types... args){
    auto res = std::make_tuple( create( std::forward<Types>( args ) )... );
}

int main(){
   using IF = std::tuple<IntegerField, int>;
   using SF = std::tuple<StringField, std::string>;

   Person person;

   createField<IF, SF>({person.id(), 42},{person.name(), "Joe"});
}
#包括
#包括
#包括
#include//For std::index\u sequence\u For
类整数域{
公众:
整数域(int i){}
};
StringField类{
公众:
StringField(std::string s){}
};
班主任{
公众:
Person():mId{5},mName{“empty”}{
IntegerField id(){return mId;}
StringField name(){return mName;}
私人:
积分场;
StringField mName;
};
名称空间详细信息{
模板
自动创建(常量std::tuple&t,std::index_sequence seq){
返回std::make_unique(std::get(t)…);
}
}
模板
自动创建(const std::tuple&t)->std::enable\u if\u t{

返回详细信息::创建(t,std::index_sequence_for

您希望
uPtr
的类型是什么?它将是
std::tuple
?@arnes-我希望它是std::unique_ptr或std::unique_ptr,具体取决于传递的参数。在您的示例中,您正在传递这两个参数,因此
uPtr
应该以某种方式同时表示IntegerField和StringField。Bu我想你想单独专门化类型吗?@arnes,当然,我想单独专门化。我想args将单独解包(每个元组参数)?请详细说明this@arnes,已修复,现在正在编译!