Mam funkcję, która pobiera argumenty określonego typu szablonu; uproszczona wersja może wyglądać następująco:Czy istnieje sposób kanoniczny pozwalający na niejawną konwersję niestanowiącego stałego typu szablonu na stały?
#include <type_traits>
template <typename T>
struct foo
{
// default constructor
foo() { }
// simple copy constructor that can construct a foo<T> from a foo<T>
// or foo<const T>
foo(const foo<typename std::remove_const<T>::type> &) { }
};
Funkcjonalnie foo
zachowuje się podobnie do shared_ptr<T>
z innej funkcjonalności rozszerzenie, które nie odnoszą się do tej kwestii. Semantyka funkcji dyktuje, że woli przyjąć foo<const T>
. foo<const T>
jest niejawnie constructible z foo<T>
, więc chciałbym, aby móc zrobić coś jak następuje:
template <typename T>
void bar(foo<const T> f) { }
int main()
{
bar(foo<const int>()); // fine
bar(foo<int>()); // compile error
}
To nie działa, ponieważ nie istnieją żadne przeciążenia pasujące do bar
że wziąć foo<int>
(chociaż foo<const int>
może być niejawnie wykonana z foo<int>
rozdzielczość przeciążenie w porozumieniu z szablonu instancji wydaje się być bardziej restrykcyjne niż to.
Czy istnieje kanoniczny sposób do osiągnięcia tego celu? wiem, że mogę przedstawić drugą przeciążenie dla bar()
że bierze foo<T>
i wywołuje ręcznie do bar(foo<const T>)
, ale chciałbym uniknąć duplikowania, jeśli to możliwe.
działa dobrze dla mnie, jak pokazano w moim pre-kompilator C++ 11 (bcc32) , ale nie na ideone.com za pomocą C++ 14 ("typy" const T 'i "int" mają niekompatybilne kwalifikatory cv). –
Czy to tylko ja, czy zrobiłeś to na odwrót? Kopia c-tor używa 'remove_const', a twój opis i kod używający' bar' dotyczą przypadku, w którym ** dodaje ** 'const'. –
@ YehezkelB .: Chodzi o to, że 'foo' powinno być możliwe do skonstruowania z 'foo ', więc musisz usunąć 'const' w argumencie do konstruktora. Myślę, że * jest poprawny, jak napisano. –