2016-06-07 11 views
5

varsayalım yabancı parametre paketten alınan bağımsız değişken türleri ile bir işlev bildirilmesi böyle çeşitli şekillerde bir TypeList.Ben <pre><code>template<typename... Types> struct TypeList {}; </code></pre> <p></p> Şimdi başka sınıfta ben üretebilir tipi listesinin çeşit

template<class T> struct MyClass { 
    using MyList = TypeList<T, typename Something<T>::type, SomethingElse>; 
    // ... 
}; 

Bu tür listeden çıkarılan argüman türleriyle bir yöntemi nasıl bildirebilirim? Ben MyList = TypeList<int, float, const char*> set Örneğin, ben

void my_method(int, float, const char*) 

ilan edilmesi için bir yöntem diliyorum.

+1

argümanlarını sınırlamak için static_assert ve std::is_same kullanabilirsiniz bilinmeyen imzanın bir işlevi ile (örneğin: void my_method (T0, T1, T2, ... TN) 'N = = büyük) ile ne yapmalı? –

+0

@ DieterLücking Çok sayıda şey! (Bu sorulan soru ile alakasız) –

cevap

4

yöntemden uygulayan bir temel sınıf türetmek olabilir: Eğer yapacaksın

template <typename> struct MethodProvider; 

template <typename ...Args> 
struct MethodProvider<TypeList<Args...>> 
{ 
    void my_method(Args ...args); 
}; 

template <typename T> 
struct MyClassAux 
{ 
    using MyList = TypeList<T, typename Something<T>::type, SomethingElse>; 
}; 

template <typename T> 
struct MyClass 
    : private MyClassAux<T> 
    , private MethodProvider<typename MyClassAux<T>::MyList> 
{ 
    using typename MyClassAux<T>::MyList; 
    using MethodProvider<typename MyClassAux<T>::MyList>::my_method; 

    // ... 
}; 
+0

Vay, güzel üç sınıf şeması. Bu mümkün olan en basit yol mu? –

+1

@TigranSaluev: Bu en basit şey * Ben * düşünebilirim, ama bekle ve gör ... düzenlemeye dikkat et, bir uzmanlık eksik. –

+0

Bu arada, böyle bir ortamda 'myClass'' my_method'dan başka yöntem ve alanlara erişmek mümkün mü? –

0

Sen my_method

#include <iostream> 
#include <string> 
#include <vector> 
#include <type_traits> 

template<typename... Types> struct TypeList {}; 

template<class T> struct MyClass { 
    using MyList = TypeList<int, T>; 

    template<typename ...Args> 
    void my_method(Args ...args) { 
     static_assert(std::is_same<MyList, TypeList<Args...>>::value, "invalid arguments"); 
     auto dummy = {(std::cout << args << "\n", 0)...}; 
     (void)(dummy); // avoid variable warning 
    } 
}; 

int main() 
{ 
    MyClass<float> c; 
    c.my_method(1, 2.3f); 
// c.my_method(1, ""); // unmatched arguments won't compile 
// c.my_method(1); 
} 

Online Demo

+1

Bu yöntem, yöntem çağrılırken öldürür, değil mi? (Çünkü sadece "oh noes, bu const T & olamaz, tam olarak T olması gerekiyor" gibi olacak) –

+2

@TigranSaluev Haklısınız. Ama std :: is_same' özel bir sürümünü kullanabilirsiniz. Std :: decay 'ile ilk olarak kısıtlamayı serbest bırakabilirsiniz. –

+0

Bu yalnızca en önemsiz dönüşümleri düzeltir ve "float" kelimesi gibi dönüşümleri düzeltmez. –

İlgili konular