C++ 可变参数子集
我试图获取当前类包装器的可变参数子集,以实例化一个新的变量 目前我有:C++ 可变参数子集,c++,c++11,templates,recursion,variadic-templates,C++,C++11,Templates,Recursion,Variadic Templates,我试图获取当前类包装器的可变参数子集,以实例化一个新的变量 目前我有: // Reference: https://stackoverflow.com/questions/27941661/generating-one-class-member-per-variadic-template-argument // Template specialization template<typename T, typename... Next> class VariadicClass; //
// Reference: https://stackoverflow.com/questions/27941661/generating-one-class-member-per-variadic-template-argument
// Template specialization
template<typename T, typename... Next> class VariadicClass;
// Base case extension
template <typename T>
class VariadicClass<T> {
private:
T value_;
protected:
void SetField(T & value) {
value_ = value;
}
T & GetField() {
return value_;
}
};
// Inductive case
template <typename T, typename ... Next>
class VariadicClass : public VariadicClass<T>, public VariadicClass<Next...> {
public:
// Copy the values into the variadic class
template <typename F>
void Set(F f) {
this->VariadicClass<F>::SetField(f);
}
// Retrieve by reference
template <typename F>
F & Get() {
return this->VariadicClass<F>::GetField();
}
};
我想实现以下目标:
[C]: A subset of Args...
VariadicClass<[C]> * Filter(VariadicClass<Args...> input) {
return new VariadicClass<[C]>(GetSubsetFrom(input, [C]));
}
VariadicClass<int, bool, char> class1;
VariadicClass<int, bool> * variadic = Filter(class1);
您可以假设每个类型在变量类中只存在一次,并且我将始终请求当前变量类型的子集。我不知道这是否是当前可能的C++ 11?
谢谢您的帮助。首先,我认为您不应该编写自己的变量类,因为我们已经有了std::tuplein place 我想知道你是否坐在c++11上,因为它已经很旧了。即使c++14已经过时,但如果可以切换,解决方案也非常简单:
template < typename DATA, typename FILTER, std::size_t... Is>
auto Subset_Impl( const DATA& data, FILTER& filter, std::index_sequence<Is...> )
{
filter = { std::get< typename std::remove_reference<decltype( std::get< Is >( filter ))>::type>( data )... };
}
template < typename DATA, typename FILTER, typename IDC = std::make_index_sequence<std::tuple_size<FILTER>::value >>
auto Subset( const DATA& data, FILTER& filter )
{
return Subset_Impl( data, filter, IDC{} );
}
int main()
{
std::tuple< int, float, std::string, char > data { 1, 2.2, "Hallo", 'c' };
std::tuple< float, char > filter;
Subset( data, filter );
std::cout << std::get<0>( filter ) << " " << std::get<1>( filter ) << std::endl;
}
如果您真的想坐在过时的标准上,您可以轻松地实现标准库中缺少的部分。这里回答了一个相关问题:
助手模板是如何定义的,请参见:首先,我认为您不应该编写自己的变量类,因为我们已经有了std::tuplein place 我想知道你是否坐在c++11上,因为它已经很旧了。即使c++14已经过时,但如果可以切换,解决方案也非常简单:
template < typename DATA, typename FILTER, std::size_t... Is>
auto Subset_Impl( const DATA& data, FILTER& filter, std::index_sequence<Is...> )
{
filter = { std::get< typename std::remove_reference<decltype( std::get< Is >( filter ))>::type>( data )... };
}
template < typename DATA, typename FILTER, typename IDC = std::make_index_sequence<std::tuple_size<FILTER>::value >>
auto Subset( const DATA& data, FILTER& filter )
{
return Subset_Impl( data, filter, IDC{} );
}
int main()
{
std::tuple< int, float, std::string, char > data { 1, 2.2, "Hallo", 'c' };
std::tuple< float, char > filter;
Subset( data, filter );
std::cout << std::get<0>( filter ) << " " << std::get<1>( filter ) << std::endl;
}
如果您真的想坐在过时的标准上,您可以轻松地实现标准库中缺少的部分。这里回答了一个相关问题:
助手模板的定义方式也可以在以下页面上看到:在我看来,您试图重新创建轮子,在本例中,轮子是std::tuple 不管怎样,你问的对我来说很简单
template <typename ... As1, typename ... As2>
VariadicClass<As1...> * Filter(VariadicClass<As2...> in)
{
using unused = int[];
auto ret = new VariadicClass<As1...>();
(void)unused { 0, (ret->template Set<As1>(in.template Get<As1>()), 0)... };
return ret;
}
您必须明确As1。。。类型调用筛选器,所以
或者,也许更好
auto variadic = Filter<int, bool>(class1);
下面是一个完整的编译示例
#include <iostream>
template <typename, typename...>
class VariadicClass;
template <typename T>
class VariadicClass<T>
{
private:
T value_;
protected:
void SetField (T & value)
{ value_ = value; }
T & GetField ()
{ return value_; }
};
template <typename T, typename ... Next>
class VariadicClass : public VariadicClass<T>, public VariadicClass<Next...>
{
public:
template <typename F>
void Set (F f)
{ this->VariadicClass<F>::SetField(f); }
template <typename F>
F & Get()
{ return this->VariadicClass<F>::GetField(); }
};
template <typename ... As1, typename ... As2>
VariadicClass<As1...> * Filter(VariadicClass<As2...> in)
{
using unused = int[];
auto ret = new VariadicClass<As1...>();
(void)unused { 0, (ret->template Set<As1>(in.template Get<As1>()), 0)... };
return ret;
}
int main()
{
VariadicClass<int, bool, char> c1;
c1.Set<int>(42);
c1.Set<bool>(true);
c1.Set<char>('Z');
auto pC2 = Filter<int, bool>(c1);
std::cout << pC2->Get<int>() << std::endl;
std::cout << pC2->Get<bool>() << std::endl;
delete pC2;
}
离题未经请求的建议:您正在使用C++11,因此。。。尽量避免直接使用指针,尽量使用智能指针std::unique\u ptr、std::shared\u ptr等。在我看来,您似乎在试图重新发明轮子,在本例中,轮子是std::tuple 不管怎样,你问的对我来说很简单
template <typename ... As1, typename ... As2>
VariadicClass<As1...> * Filter(VariadicClass<As2...> in)
{
using unused = int[];
auto ret = new VariadicClass<As1...>();
(void)unused { 0, (ret->template Set<As1>(in.template Get<As1>()), 0)... };
return ret;
}
您必须明确As1。。。类型调用筛选器,所以
或者,也许更好
auto variadic = Filter<int, bool>(class1);
下面是一个完整的编译示例
#include <iostream>
template <typename, typename...>
class VariadicClass;
template <typename T>
class VariadicClass<T>
{
private:
T value_;
protected:
void SetField (T & value)
{ value_ = value; }
T & GetField ()
{ return value_; }
};
template <typename T, typename ... Next>
class VariadicClass : public VariadicClass<T>, public VariadicClass<Next...>
{
public:
template <typename F>
void Set (F f)
{ this->VariadicClass<F>::SetField(f); }
template <typename F>
F & Get()
{ return this->VariadicClass<F>::GetField(); }
};
template <typename ... As1, typename ... As2>
VariadicClass<As1...> * Filter(VariadicClass<As2...> in)
{
using unused = int[];
auto ret = new VariadicClass<As1...>();
(void)unused { 0, (ret->template Set<As1>(in.template Get<As1>()), 0)... };
return ret;
}
int main()
{
VariadicClass<int, bool, char> c1;
c1.Set<int>(42);
c1.Set<bool>(true);
c1.Set<char>('Z');
auto pC2 = Filter<int, bool>(c1);
std::cout << pC2->Get<int>() << std::endl;
std::cout << pC2->Get<bool>() << std::endl;
delete pC2;
}
离题未经请求的建议:您正在使用C++11,因此。。。尽量避免直接使用指针,尽量使用智能指针std::unique\u ptr、std::shared\u ptr等