2010-04-29 23 views
9

C++ 0x özelliklerinden bazılarını anlamak için kişisel deneylerimden biri: Çalıştırılacak bir şablon işlevine bir işlev işaretçisini iletmeye çalışıyorum. Sonuç olarak, yürütmenin farklı bir iş parçacığında gerçekleşmesi gerekiyor. Ancak, tüm farklı işlev türlerinde, şablonların çalışmasını sağlayamıyorum.Şablonlar, İşlev İşaretçiler ve C++ 0x

#include <functional> 

int foo(void) {return 2;} 

class bar { 
public: 
    int operator() (void) {return 4;}; 
    int something(int a) {return a;}; 
}; 

template <class C> 
int func(C&& c) 
{ 
    //typedef typename std::result_of< C() >::type result_type; 
    typedef typename std::conditional< 
     std::is_pointer<C>::value, 
     std::result_of< C() >::type, 
     std::conditional< 
      std::is_object<C>::value, 
      std::result_of< typename C::operator() >::type, 
      void> 
     >::type result_type; 
    result_type result = c(); 
    return result; 
} 

int main(int argc, char* argv[]) 
{ 
    // call with a function pointer 
    func(foo); 

    // call with a member function 
    bar b; 
    func(b); 

    // call with a bind expression 
    func(std::bind(&bar::something, b, 42)); 

    // call with a lambda expression 
    func([](void)->int {return 12;}); 

    return 0; 
} 

result_of şablon yalnız sınıf bar ve ben derleme değil yarattı aksak koşullu operatöre() bulmak mümkün görünmemektedir. Herhangi bir fikir? Const fonksiyonları ile ek sorunlarım olacak mı?

+0

Belki de derleme değil, çünkü 'func'' result_type' yerine 'int' döndürür (bu örnekte' int' tüm örneklerde 'ancak yine de bir soruna neden olabilir)? –

+0

@Chris: Hayır, nedeni bu değil. – kennytm

+0

@KennyTM - Ben düşündüm, ama yine de sorun olduğunu düşünüyorum. –

cevap

6

decltype nasıl kullanılır? i C++ 0x taslak anlamak

template <class C> 
auto func(C&& c) -> decltype(c()) { 
    auto result = c(); 
    return result; 
} 
+0

çok daha temiz görünüyor. Teşekkürler! – user328543

4

sağ aslında yeterli olmalıdır aşağıdadır:

typedef typename std::result_of<C()>::type result_type; 

yerine bunu koşullu ifadenin kullanılması, bu gcc4.5 ince derler - belki var Kullandığınız derleyicide bir hata bulundu?

+0

Ben de öyle düşündüm ama derleme yapmamıştı. Tüm karmaşık şartlı bu etrafında çalışmak için yaratıldı. – user328543

+1

@ user328543: Şartlı durumunuzu açıklarsam ve daha önce yorumladığı satırı kullanırsam, gcc4.5'te kesinlikle iyi bir şekilde derler. –

2

Şablonunuzu başlatmaya başladım, ancak GCC, result_of'un her kullanımından şikayet ediyor.

template <class C> 
int func(C&& c) 
{ 
    //typedef typename std::result_of< C() >::type result_type; 
    typedef typename std::conditional< 
     std::is_pointer<C>::value, 
     // C++0x still requires "typename" sprinkles: 
     typename std::result_of< C() >::type, 
     typename std::conditional< 
      std::is_object<C>::value, 
      // result_of takes a *type* as an argument, not an object: 
      //typename std::result_of< decltype(&C::operator()) >::type, 
      // Or better: 
      typename std::result_of<C>::type, 
      void> 
     >::type result_type; 
    result_type result = c(); 
    return result; 
} 

int main(int argc, char* argv[]) 
{ 
    // according to GCC, func(foo) passes a function reference. 
    func(foo); 

İlk hata iletisi:

rof.cpp:23:17: error: invalid use of incomplete type 'struct std::result_of<int (&)()>' 

result_of standardında belirtildiği şekilde uygulanan, yüzden GCC kısmi uzmanlaşma bildiriminde sözde prototip sözdizimi maç olamaz görünür.

+0

İşlevler için başvurular çalışmalıdır: * "Fn, bir işlev nesnesi türü (20.8), işlev referansı veya işlev nesnesi türüne başvuru olmalıdır." * –

+1

@gf: cool, iyi yorumu yararlı bir şekilde pedantic olarak saklayacağım. Her iki durumda da, GCC'nin hata mesajı açık bir şekilde iyi kodu reddettiğini gösteriyor. – Potatoswatter

+0

@gf: yanlış iplik? – Potatoswatter