template ای که فقط روی کلاس های مشتق شده از کلاس خاص کار کند - هفت خط کد انجمن پرسش و پاسخ برنامه نویسی

template ای که فقط روی کلاس های مشتق شده از کلاس خاص کار کند

+2 امتیاز

سلام جطوری میشه template ای نوشت که فقط روی کلاس هایی که از یک کلاس خاص مشتق شده کار کنه

مثلا فرضا اگر کلاس های من ساده شدشون به این شکل تعریف شده باشه  :

class Base{}
class Child:public Base{}
class Child2:public Child2{}

class A{}

template<class T>
class MyTemplate{}

می خوام کد های زیر ارور بدن و کار نکن :

MyTemplate<int> a;//error
MyTemplate<A> a;//error
MyTemplate<std::vector> a;//error

و فقط کلاس هایی که از Base مشتق شدن رو بشه داخلش استفاده کرد :

MyTemplate<Child1> a;//ok
MyTemplate<Child2> a;//ok

 

سوال شده مرداد 19, 1393  بوسیله ی Mad (امتیاز 245)   10 35 47
دوباره تگ گذاری شد مهر 9, 1393 بوسیله ی BlueBlade

1 پاسخ

+4 امتیاز
 
بهترین پاسخ

برای این که بفهمید آیا کلاس از نوع خاصی مشتق شده یا نه زمان کامپایل میشه از متد std::is_base_of استفاده کرد

	std::cout << std::is_base_of<Base, Child>::value;
	std::cout << std::is_base_of<Base, Child2>::value;

کد بالا ۲ تا ۱ یا true چاپ می کنه 

 

حالا برای این که template به اون شکلی که گفتید کار کنه 2 کار میشه انجام داد:

 

1_ از static_assert استفاده کنید (اجرای زنده کد زیر‌)

#include <iostream>
#include <type_traits>

class Base{};
class Child :public Base{};
class Child2 :public Child{};

class A{};

template<class T>
class MyTemplate{
	static_assert(std::is_base_of<Base,
		typename/* typename dakhel gcc lazem nist*/ T>::value,
								"Wrong template parameter");
};
int main()
{
	MyTemplate<Child> a;//ok
	MyTemplate<Child2> b;//ok

	//MyTemplate<int> c; compile error
	//MyTemplate<A> d; compile error
}

 

2_ یک پارامتر اضافی برای template بزارید و از std::enable_if استفاده کنید که فقط وقت هایی که type درست بود template مقدار صحیح  بگیره و اجرا بشه (SFINAE ) (اجرای زنده )

template<class T,
	    class DummyType=
		    typename std::enable_if<
		    std::is_base_of<Base,typename T>::value,std::true_type>::type>
class MyTemplate {};

دقت کنید که در کد بالا داخل gcc اون typename قبل از T نباید باشه ولی داخل visual studio باید باشه 

ضمنا اگر کامپایلرتون از c++11 پشتیبانی نمی کنی میتونید خودتون is_base_of و enable_if رو بنویسید البته یکم سخته .
پاسخ داده شده مرداد 19, 1393 بوسیله ی BlueBlade (امتیاز 15,315)   15 18 89
انتخاب شد شهریور 5, 1393 بوسیله ی Mad
...