2017-08-04 17 views
5

Aşağıdaki örnekte, ileri bildirim struct Y bildirim beyanı yeterli değildir. Eğer X :: b'yi açıklarsanız, Y tam bir yapısal bildirime sahip olduğundan, X yalnızca ileri bildirime sahiptir. Dairesel beyanların gerekli olacağı diğer sınıflardan bahsedilmesini gerektiren sınıflardaki değişkenler nasıl başlatılır?

Ideone

aşağıdaki

#include <functional> 
#include <iostream> 

struct Y; 

struct X 
{ 
    std::function<bool(Y&)> b{[] (auto& y_) { return y_.a; }}; 

    bool a{false}; 
}; 

struct Y 
{ 
    std::function<bool(X&)> b{[] (auto& x_) { return x_.a; }}; 

    bool a{true}; 
}; 

int main() 
{ 
    return 0; 
} 
Ben ile gelebilir düzeltmedir:

#include <functional> 
#include <iostream> 

struct Y; 

struct X 
{ 
    X(); 
    std::function<bool(Y&)> b; 

    bool a{false}; 
}; 

struct Y 
{ 
    Y(); 
    std::function<bool(X&)> b{[] (auto& x_) { return x_.a; }}; 

    bool a{true}; 
}; 

X::X() : b([] (auto& y_) { return y_.a; }) {} 
Y::Y() : b([] (auto& x_) { return x_.a; }) {} 

int main() 
{ 
    return 0; 
} 

Ideone

Ve bu örnekte çalışırken, sınıflar polimorfik olsaydı, bu Sırasıyla bu sınıfların çocuklarında using X::X; veya using Y::Y; gerektirir.

Başlık dosyalarının kendisinde bunu yapmanın bir yolu var mı?

+2

Neden mesela gerekir X :: X 'kullanarak çocuk sınıfında? Kurucu hala * sınıfın içinde * bildirilir, sadece sınıf tanımının dışında * tanımlanmış * (uygulanmış) (yani satır içi değil). –

+0

Bu mu? Denememe izin verin – kim366

+1

İhtiyacınız olan her şey [uygun başlık/uygulama yapısı] (https://stackoverflow.com/questions/625799/resolve-header-include-circular-dependencies) ve üyelerin sınıf gövdesinde başlatılması yerine yapıcı başlatma listesinde yapın. – NathanOliver

cevap

0

Bunu yapabilirsiniz:

#include <functional> 

template <typename T> bool (*get_lambda())(T&) {return [] (auto& y_) { return y_.a; };}; 

struct Y; 

struct X 
{ 
    std::function<bool(Y&)> b{get_lambda<Y>()}; 

    bool a{false}; 
}; 

struct Y 
{ 
    std::function<bool(X&)> b{get_lambda<X>()}; 

    bool a{true}; 
}; 

int main() 
{ 
    return 0; 
} 
+0

Tamam, tanımı tanımı ayrı bir başlıkta genel bir işleve yerleştirin. Mantıklı görünüyor. – kim366