LINUX.ORG.RU

Шаблоны шаблонов шаблонами

 


0

5

Есть такая вот рабочая штука:

#include <memory>

class A {
public:
};

template <template <typename, typename> class Ptr>
void foo(Ptr<A, std::default_delete<A> >& ptr)
{
}
 
int main() {
    std::unique_ptr<A> ptr(new A);
    
    foo(ptr);
}

Хочется избавиться от явного указания std::default_delete<A>. Вопрос - как? Смысл шаблона foo в том, что аргумент foo должен быть автоматическим указателем (unique_ptr, shared_ptr и т.п.) именно на объект типа A.

★★★★★

template <template <typename, typename> class Ptr, typename T>
void foo(Ptr<A, T>& ptr)
{
}
Pavval ★★★★★ ()
template <template <typename, typename> class Ptr>
void foo(Ptr<A, std::default_delete<A> >& ptr)
{
}

template <template <typename> class Ptr>
void foo(Ptr<A>& ptr)
{
}


int main() {
    std::unique_ptr<A> ptr(new A);

    foo(ptr);
}
anonymous ()
Ответ на: комментарий от asaw

На самом деле надо что-то вроде

template<class T>
auto f (T& ptr) -> std::enable_if<std::is_same<decltype(*ptr), A&>::value>::type
{
}

vzzo ★★★ ()
Последнее исправление: vzzo (всего исправлений: 3)
Ответ на: комментарий от vzzo

Нет, мне не нужно быть уверенным, что обычная ссылка - ссылка на объект определенного типа, так бы я просто написал A& без всяких шаблонов. Мне нужно получать именно смарт-указатель (не важно какой именно - потому и шаблоны) на объект определенного типа.

asaw ★★★★★ ()
#include <memory>
#include <type_traits>

template <typename Arg, typename T>
struct is_smart_pointer_of : std::false_type {};

template <typename A, typename B>
struct is_smart_pointer_of<std::unique_ptr<A, B>, A> : std::true_type {};

template <typename A>
struct is_smart_pointer_of<std::shared_ptr<A>, A> : std::true_type {};

template <typename A>
struct is_smart_pointer_of<std::weak_ptr<A>, A> : std::true_type {};

class A {
public:
};

class B {
public:
};

template <typename T>
void foo(T& ptr) {
	static_assert(is_smart_pointer_of<T, A>::value, "ptr should be a smart pointer of given type");
}
 
int main() {
	std::unique_ptr<A> a(new A);
	std::shared_ptr<A> b(new A);
	
	A* c = new A();
	
	std::shared_ptr<B> d(new B);

	foo(a);
	foo(b);
//	foo(c);
//	foo(d);
}
Kuzy ★★★ ()
Ответ на: комментарий от Kuzy

Епт, ОП всего-лишь за молочком сходить хотел...

Pavval ★★★★★ ()
Ответ на: комментарий от Pavval

C++ слишком страшный что бы с ним за молочком ходить.

Kuzy ★★★ ()

понаплодили недоумки кучу «умных» указателей, вместо того чтобы добавить gcnew и gc class. но нет, спятивший страус и кучка его таких же дружков решили сделать, чтобы было все архисложно и архинеэффективно по времени разработки. закручивание шурупа плоскогубцами называется, да

anonymous ()
Ответ на: комментарий от Kuzy

Так работает:

#include <memory>

class A {
public:
};

template <template <typename, typename...> class Ptr, typename... D>
void foo(Ptr<A, D...>& ptr)
{
}
 
int main() {
    std::shared_ptr<A> ptr(new A);
    
    foo(ptr);
}

Pavval прав: мне в космос на этом велосипеде лететь не надо.

asaw ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.