2015-04-28 16 views
6

Powyższy kod nie działa. Rzeczywiście domyślny skonstruowany obiekt f w konstruktorze Foo skarży się, że wartość val nie została zadeklarowana w zakresie. Nie rozumiem, dlaczego nie zostało to zadeklarowane.Nie zadeklarowana zmienna w obiekcie domyślnie konstruowanym w konstruktorze

struct Foo2 
{ 
    Foo2(int val) 
    {} 
}; 

struct Foo 
{ 
    Foo(int val, Foo2 f = Foo2(val)) 
    {} 
}; 

int main() 
{ 
    Foo f(1); 
    return 0; 
} 
+1

Nie można użyć parametrów domyślnych parametrów. – chris

+2

To pytanie nie zawiera żadnych domyślnych konstruktorów. –

Odpowiedz

5

Zgodnie z C++ Standard (8.3.6 Domyślne argumenty):

9 Domyślne argumenty są oceniane za każdym razem t on nazywa się funkcja. Kolejność oceny argumentów funkcji jest nieokreślona. W związku z tym parametry funkcji nie mogą być używane w domyślnym argumencie , nawet jeśli nie są analizowane. Parametry funkcji zadeklarowanej przed domyślnym argumentem są w zakresie i mogą ukrywać nazwy i nazwy członków klasy.

W dowolnym C++ (nie tylko C++ 2014) można przeciążać konstruktora. Na przykład

struct Foo 
{ 
    Foo(int val) 
    { Foo2 f(val); /*...*/ } 
    Foo(int val, Foo2 f) 
    {} 
}; 

Albo można użyć przekazał mu uprawnienia konstruktora (jeśli kompilator obsługuje nowy standard)

struct Foo 
{ 
    Foo(int val) : Foo(val, Foo2(val)) 
    {} 
    Foo(int val, Foo2 f) 
    {} 
}; 
2

Tak właśnie działa język; Domyślne argumenty nie mogą zależeć od innych parametrów, ponieważ kolejność ich inicjalizacji pozostaje nieokreślona.

w C++ 11 lub później, można obejść ten problem z przeciążeniem:

Foo(int val) : Foo(val, Foo2(val)) {} 
+0

Możesz też użyć przeciążenia. – refi64

+1

@ kirbyfan64sos Co to jest? – LogicStuff

+2

@ kirbyfan64sos: Używam przeciążania. –

0
struct Foo2 
{ 
    int x; 
    Foo2(int val): x(val) {} 
}; 

struct Foo 
{ 
    int y; 
    Foo2 f2; 
    Foo(int val, Foo2 f): y(val), f2(f) {} 
    Foo(int val): y(val), f2(val) {} 
}; 

int main() 
{ 
    Foo f(1); 
} 
+1

Zakładamy, że 'f2' jest zmienną składową' Foo'. – Beta

0

Można używać szablonów, aby rozwiązać ten:

struct Foo2 
{ 
    Foo2(int val) 
    {} 
}; 

template <int val> 
struct Foo 
{ 
    Foo(Foo2 f = Foo2(val)) 
    {} 
}; 

int main() 
{ 
    Foo<1> f = Foo<1>(); 
    return 0; 
} 
+0

Tak, wiem, ale chcę, aby 'val' był zmienną runtime –

+1

Ahh, powinieneś był to powiedzieć. –

Powiązane problemy