b00rt00s Temat założony przez niniejszego użytkownika |
[C++11] Dedukcja parametru szablonu » 2013-08-21 22:58:42 Mam taki program: #include <type_traits> #include <memory>
template < typename T > struct smart_ptr_types;
template < typename T > using shared_ptr_type = typename smart_ptr_types < T >::shared_ptr_type;
template < class T, class U > inline shared_ptr_type < T > shared_ptr_type_static_cast( const shared_ptr_type < U >& r );
#include "first.h"
template < typename T > struct smart_ptr_types { typedef std::shared_ptr < T > shared_ptr_type; };
template < class T, class U > inline shared_ptr_type < T > shared_ptr_type_static_cast( const shared_ptr_type < U >& r ) { return std::static_pointer_cast < T >( r ); }
#include "second.h"
class A { }; class B : public A { };
int main() { shared_ptr_type < A > b( new B() ); shared_ptr_type < B > c = shared_ptr_type_static_cast < B >( b ); }
I taki błąd kompilacji: ../../main.cpp: In function 'int main()': error: no matching function for call to 'shared_ptr_type_static_cast(shared_ptr_type<A>&)' shared_ptr_type<B> c = shared_ptr_type_static_cast<B>(b); ^ note: candidate is: note: template<class T, class U> shared_ptr_type<T> shared_ptr_type_static_cast(shared_ptr_type<U>&) inline shared_ptr_type<T> shared_ptr_type_static_cast( const shared_ptr_type<U>& r ) ^ note: template argument deduction/substitution failed: note: couldn't deduce template parameter 'U' shared_ptr_type<B> c = shared_ptr_type_static_cast<B>(b); ^ Jak widać kompilator nie może wydedykować drugiego parametru szablonowej funkcji, choć sprawa wydaje się oczywista. Pomaga oczywiście wywołanie: shared_ptr_type < B > c = shared_ptr_type_static_cast < B, A >( b ); Jednak bardzo mi zależy na tym, aby kompilator mógł samodzielnie wydedukować drugi parametr szablonu. W czym leży błąd? |
|
DejaVu |
» 2013-08-21 23:34:18 #include <type_traits> #include <memory>
template < typename T > struct smart_ptr_types { typedef std::shared_ptr < T > shared_ptr_type; };
template < typename T > using eksperyment = typename smart_ptr_types < T >::shared_ptr_type;
int main() { return 0; }
http://stackoverflow.com/questions/2795023/c-template-typedefSprawdź czy to działa pod Twoim kompilatorem. Visual C++ 2012 chyba nie wspiera tej części standardu. |
|
DejaVu |
» 2013-08-21 23:36:13 template < typename T > struct smart_ptr_types;
template < typename T > using shared_ptr_type = typename smart_ptr_types < T >::shared_ptr_type;
generalnie to z Twojego kodu nie ma prawa zadziałać, bowiem deklarujesz tylko i wyłącznie istnienie struktury, a nie tego co ona zawiera. Pisząc: smart_ptr_types < T >::shared_ptr_type
definicja struktury smart_ptr_types musi być już znana - w Twoim przypadku jest ona nieznana. |
|
b00rt00s Temat założony przez niniejszego użytkownika |
» 2013-08-21 23:43:26 generalnie to z Twojego kodu nie ma prawa zadziałać, bowiem deklarujesz tylko i wyłącznie istnienie struktury, a nie tego co ona zawiera. Pisząc: (...) definicja struktury smart_ptr_types musi być już znana - w Twoim przypadku jest ona nieznana. |
1. W main.cpp definicja struktury smart_ptr jest już znana, bo dołączam oba nagłówki. 2. Gdyby w tym właśnie tkwił problem, to jakim cudem zadziałała ta linia: shared_ptr_type < A > b( new B() ); Nie twierdzę, że mam rację, ale wydaje mi się, że gdybyś Ty miał rację, to działanie kompilatora w tej kwestii byłoby w mojej opinii niespójne. P.S. Właśnie sprawdziłem, że działa również takie przypisanie: std::shared_ptr < A > x = b; P.S.2. Zapomniałem dodać: używam GCC 4.8.1 |
|
b00rt00s Temat założony przez niniejszego użytkownika |
» 2013-08-22 00:06:45 Uprościłem nieco program ale błąd kompilacji nadal wsytępuje. Oto uproszczony kod: template < typename T > struct smart_ptr_types { typedef std::shared_ptr < T > shared_ptr_type; };
template < typename T > using shared_ptr_type = typename smart_ptr_types < T >::shared_ptr_type;
template < class T, class U > inline shared_ptr_type < T > shared_ptr_type_static_cast( const shared_ptr_type < U >& r ) { return std::static_pointer_cast < T >( r ); }
class A { }; class B : public A { };
int main() { shared_ptr_type < A > b( new B() ); std::shared_ptr < A > x = b; shared_ptr_type < B > c = shared_ptr_type_static_cast < B >( b ); } To jawnie dowodzi, że brak definicji klasy smart_ptr_types przed deklaracją szablonu shared_ptr_type nie był źródłem problemu. |
|
DejaVu |
» 2013-08-22 00:09:50 #include <type_traits> #include <memory>
template < typename T > struct smart_ptr_types { typedef std::shared_ptr < T > shared_ptr_type; };
template < typename T > using shared_ptr_type = typename smart_ptr_types < T >::shared_ptr_type;
template < class T, class U > inline shared_ptr_type < T > shared_ptr_type_static_cast( const U & r ) { return std::static_pointer_cast < T >( r ); }
class A { }; class B : public A { };
int main() { shared_ptr_type < A > b( new B() ); shared_ptr_type < B > c = shared_ptr_type_static_cast < B >( b ); }
|
|
b00rt00s Temat założony przez niniejszego użytkownika |
» 2013-08-22 00:14:16 OK, to rozwiązuje mój problem. Zastanawia mnie jednak jak w poprzednim przypadku działa kompilator. Na tzw. chłopski rozum wszystko było jasne i jednoznaczne. Czegoś mu jednak brakowało do wydedukowania tego parametru. Chciałbym to zrozumieć. |
|
DejaVu |
» 2013-08-22 00:19:12 Po prostu miałeś niezgodność typów. void funkcja( const szablon < szablon < int > >& argument ) { }
szablon < int > zmienna; funkcja( zmienna );
|
|
« 1 » 2 |