2015-02-24 11 views
6

C Anonim Sınıfı ++ ile Arayüzü Uygulamakböyle Anonim sınıfı ile bir <code>interface</code> uygulayabilir java olarak

System.out.println(testIf("", String::isEmpty)); 

biz c bunu nasıl ++?

#include "stdafx.h" 
#include <iostream> 
#include <string> 
using namespace std; 

template <class T> 
class Predicate 
{ 
public: 
    virtual bool test(T) = 0; 
}; 

template <class T> 
bool testIf(T t, Predicate<T> predicate) 
{ 
    return predicate.test(t); 
} 

int main() 
{ 
    class : public Predicate <string> { 
    public: 
     virtual bool test(string s) 
     { 
      return s.length() == 0; 
     } 
    } p; 
    string s = ""; 
    cout << testIf(s, p); 
    cin.get(); 
    return 0; 
} 

Hata: işlev şablonu "TESTIF" Hiçbir örnek argüman listesi argüman türleri eşleşir: (std::string, class <unnamed>)

Aşağıdaki kodu ama derleme hatası alıyorum yazdı

Burada sorun nedir? Bunu yapmanın başka yolları var mı?

Teşekkürler!

+2

sen http://stackoverflow.com/questions/991062/passing-unnamed-classes-through-functions bakabilirsiniz – Prashant

cevap

9

burada yanlış olan ne? polimorfizmi çalışması için (eğer isterseniz veya pointer)

, başvuruyla taban sınıfını geçmesi gerekiyor: yani sabit ile

bool testIf(T t, Predicate<T> & predicate) 
          ^

oldukça kokuyor rağmen, kod, benim için çalışıyor tadı için Java çok fazla.

bunu yapmak için başka yollar var?

C++ 11 veya daha sonraki sürümlerde, bir lambda hem performans hem de kod açısından daha verimli olacaktır. Bir temel sınıftan tanımlama ve devralma ihtiyacını ortadan kaldırır ve sanal işlevi çağırır.

template <class T, class Predicate> 
bool testIf(T t, Predicate predicate) 
{ 
    return predicate(t); 
} 

testIf(s, [](string const & s){return s.length() == 0;}); 

(C++ 11 önce, bir fonksiyon nesnesi ile aynı şeyi yapabilirdi. Biraz daha ayrıntılı, ama yine de kalıtım yaklaşımının tersine, daha verimli kod kısa vermiştir.)

3

C++ tek referans ve işaretçi türlerinde polimorfizm destekler. o zaman da bu işleve Predicate alt sınıflarını geçebilir

template <class T> 
bool testIf(T t, Predicate<T> & predicate) 
{ 
    return predicate.test(t); 
} 

için yöntemini değiştirme.

+0

İşte ben bunu görmedim, çok doğru :) – amchacon

3

Sen işlevi için bir işaretçi kullanabilirsiniz:

#include "stdafx.h" 
#include <iostream> 
#include <string> 
using namespace std; 

template <class T> 
class Predicate 
{ 

public: 
    bool (*test)(T); 
}; 

template <class T> 
bool testIf(T t, Predicate<T> predicate) 
{ 
    return predicate.test(t); 
} 

bool one_test(string e) 
{ 
    return e.length() == 0; 
} 

int main() 
{ 
    Predicate<string> p; 
    p.test = one_test; 
    string s = ""; 
    cout << testIf(s, p); 
    cin.get(); 
    return 0; 
} 
3

yılında Ben polimorfizm posibility görmezden çünkü referanslar olduğunda,

template <class T> 
bool testIf(T t, Predicate<T>* predicate) 
{ 
    if (predicate == nullptr) return true; 
    return predicate->test(t); 
} 

int main() 
{ 
    class : public Predicate <string> { 
    public: 
     virtual bool test(string s) 
     { 
      return s.length() == 0; 
     } 
    } p; 
    string s = ""; 
    cout << testIf(s, &p); 
    cin.get(); 
    return 0; 
} 

genellikle işaretçileri kullanmayı tercih: Bu (polimorfizm) için sırası TESTIF işaretçi veya başvuru yüklemi geçmek zorunda, çalışmak Kullanılmış. Öte yandan, nullptr için kontrol etmeniz gereken ve de sözdizimi eskisi kadar hoş olmayan bir dezavantaja sahiptir.

A bu lambda'lar Ör kullanımı olacağını uygulanması daha yaygın yolu:

template <class T,class Pred> 
bool testIf2(T t, Pred predicate) 
{ 
    return predicate(t); 
} 

int main() 
{ 
    auto pred = [](const string& s){return s.length() == 0; }; 
    string s = ""; 
    cout << testIf2(s, pred); 
    cin.get(); 
    return 0; 
}