2016-10-20 13 views
7
#include <cstdio> 

class builtin_pack 
{ 
    long v[4]; 
public: 
    builtin_pack (long v1, long v2, long v3, long v4) : v{v1, v2, v3, v4} {} 
    void builtin_op() 
    { 
     printf ("%lx,%lx,%lx,%lx\n", v[0], v[1], v[2], v[3]); 
    }; 
    template<typename Func, typename... Targs> 
    void builtin_apply (Func f, Targs ... t) 
    { 
     for (int i = 0; i < 4; i++) 
     { 
      v[i] = f (t.v[i]...); 
     } 
    } 
}; 

class pack : builtin_pack 
{ 
public: 
    pack (long v1, long v2, long v3, long v4) : builtin_pack (v1, v2, v3, v4) {} 
    template<typename Func, typename... Targs> 
    pack& apply (Func f, Targs ... t) 
    { 
     this->builtin_apply (f, t...); 
     return *this; 
    } 
    void op() 
    { 
     this->builtin_op(); 
    } 
}; 

int main() 
{ 
    pack p1{0xff, 0x0f, 0xf0, 0x06}, p2{0x0f00, 0xf000, 0x6700, 0xff00}; 
    pack p3{0x12340000, 0x56780000, 0x45120000, 0xdead0000}; 
    p3.apply ([] (long i, long j, long k)->long{return i | j | k;}, p1, p2, p3); 
    p3.op(); 
    return 0; 
} 

Ten kod kompiluje się z błędem:Jak mogę używać szablonu variadic w C++, zachowując jednocześnie swoją klasę implementatora?

main.cpp:17:24: error: cannot cast 'pack' to its private base class 'builtin_pack' 
      v[i] = f (t.v[i]...); 
        ^
main.cpp:29:15: note: in instantiation of function template specialization 'builtin_pack::builtin_apply<(lambda 
     at main.cpp:42:16), pack, pack, pack>' requested here 
     this->builtin_apply (f, t...); 
      ^
main.cpp:42:8: note: in instantiation of function template specialization 'pack::apply<(lambda at 
     main.cpp:42:16), pack, pack, pack>' requested here 
    p3.apply ([] (long i, long j, long k)->long{return i | j | k;}, p1, p2, p3); 
    ^
main.cpp:22:14: note: implicitly declared private here 
class pack : builtin_pack 
      ^~~~~~~~~~~~ 
main.cpp:17:26: error: 'v' is a private member of 'builtin_pack' 
      v[i] = f (t.v[i]...); 
         ^
main.cpp:22:14: note: constrained by implicitly private inheritance here 
class pack : builtin_pack 
      ^~~~~~~~~~~~ 
main.cpp:5:10: note: member is declared here 
    long v[4]; 
     ^
2 errors generated. 

Co chcę zrobić jest wdrożenie metody mapowania z niestandardowych funkcji (lambda) (zwanego „zastosuj”). Działa bez problemu, gdy nie ma hierarchii prywatnego implementatora-opakowania publicznego, więc gdy tablica v jest właśnie w klasie, kompiluje się i działa zgodnie z oczekiwaniami. Jednak nie działa, gdy dane są przechowywane w prywatnie odziedziczonej klasie.

Struktura klasy jest prywatną klasą implementatora wraz z klasą otoki, a w środku napotkałem ten błąd.

Czy użyłem szablonu variadic w niewłaściwy sposób? Czy jest dostępne obejście?

(Przepraszam za moją słabą ekspresję jak jestem nowicjuszem w C++ i stackoverflow i non-native speaker języka angielskiego, a zmiana lub sugestia pytanie jest mile widziane, o ile pierwotna intencja jest zarezerwowany!)

+0

http://stackoverflow.com/a/7808401/493106 – xaxxon

Odpowiedz

4

Twój problem polega na tym, że z dziedziczeniem prywatnym nie można przekonwertować z pack* na builtin_pack* (poza tym, że jest to pack). Jeśli nie rzucać go, kod kompiluje, choć nie jestem pewien, czy to jest to, czego szukali:

template<typename Func, typename... Targs> 
pack& apply (Func f, Targs ... t) 
{ 
    this->builtin_apply (f, static_cast<builtin_pack&&>(t)...); 
    return *this; 
} 

live demo