2016-10-27 16 views
5

Czy istnieje sposób, aby uzyskać wskaźnik funkcji członka do konstruktora kopiowania klasy? Wiem, jak zdefiniować i użyć normalnego wskaźnika funkcji członka, ale nie mogę wymyślić sposobu, aby go uzyskać.Jak mogę uzyskać wskaźnik funkcji członka do konstruktora kopiowania klasy?

+5

Nie możesz. Konstruktory nie mają nazw. –

+0

Nie możesz, ale w zależności od tego, co chcesz zrobić, możesz znaleźć obejście, używając lamdy. To znaczy. umieszczenie go w lamdzie. – Makaronodentro

+8

To brzmi jak [problem XY] (http://xyproblem.info/). Załóżmy, że jakoś udało się uzyskać wskaźnik do konstruktora (nie, że można) - w jaki sposób można go użyć? Jaki jest faktyczny problem, który próbujesz rozwiązać? –

Odpowiedz

3

Zgodnie ze standardem C++ "adres konstruktora nie zostanie wzięty", więc nie można zrobić tego, o co prosisz. Istnieje jednak proste obejście tego problemu. Poniższy kod zwraca wskaźnik funkcji do funkcji, która tworzy kopię jego danych wejściowych.

template<class obj> auto GetCopyConstructor() -> obj(*)(const obj&) 
{ 
    return +[](const obj& o) { return obj(o); }; 
}  
struct foo 
{ 
    std::string msg; 
    foo(const std::string& my_msg) { msg = my_msg; } 
    foo(const foo&) = default; 
}; 
int main() 
{ 
    auto make_copy = GetCopyConstructor<foo>(); 
    foo a("Hello, world"); 
    foo b = make_copy(a); 
    std::cout << b.msg << std::endl; 
} 

Alternatywnie: (uproszczenie, które obejmuje również dodatkowe przypadki użycia)

template<class obj> obj Copy(const obj& o) { return obj(o); } 
template<class obj> obj* CopyNew(const obj& o) { return new obj(o); } 
template<class obj> obj CopyFromPtr(const obj* o) { return obj(*o); } 
template<class obj> obj* CopyNewFromPtr(const obj* o) { return new obj(*o); } 
template<class obj> void* WhyWouldYouEvenWantToDoThis(const void* o) 
{ return new obj(*(obj*)o); } 
int main() 
{ 
    foo(*make_copy)(const foo&) = Copy<foo>; 
    foo a("Hello, world"); 
    foo b = make_copy(a); 
    std::cout << b.msg << std::endl; 
} 
+0

Jedyne brakujące wiersze to #include i #include , a kod działa zarówno w C++ 11, jak i C++ 14 przy użyciu kompilatora GCC. Jakie masz problemy? –

+0

[Nieważne] (http://stackoverflow.com/questions/18889028/a-positive-lambda-what-sorcery-is-this). Nauczyłem się czegoś nowego dzisiaj. – StoryTeller

+0

Znak + nie powinien być konieczny, nie wiesz, dlaczego on tam jest? Powinien wyzwolić niejawną konwersję po powrocie bez niej. –

Powiązane problemy