В первом примере ваша строка наследования должна выглядеть следующим образом:
ref class Test : public System::Collections::Generic::IEnumerable<B>
(на шаблоне нет ссылочного маркера)
Тогда ваша строка использования должна выглядеть так:
Test<A^> ^a = gcnew Test<A^>();
Маркеры ссылок используются в экземпляре шаблона, а не в самом шаблоне.
Вот ваш пример, скомпилированный:
using namespace System;
using namespace System::Collections::Generic;
ref class A {};
template<class B> ref class Test : public System::Collections::Generic::IEnumerable<B>
{
public:
B GetInstance()
{
return Activator::CreateInstance<B>();
}
virtual System::Collections::IEnumerator^ GetEnumeratorObj() =
System::Collections::IEnumerable::GetEnumerator
{
return nullptr;
}
virtual System::Collections::Generic::IEnumerator<B>^ GetEnumerator()
{
return nullptr;
}
};
void test()
{
Test<A^> ^a = gcnew Test<A^>();
}
Редактировать: Понял, я должен объяснить, почему это так. Насколько я понимаю, причина, по которой вы не можете указать B ^ в наследовании IEnumerable, заключается в том, что IEnumerable является универсальным с ограничением на него, а B - это параметр шаблона, который не ограничен. Шаблоны допускают гораздо более гибкий синтаксис, даже когда они управляют объектами ref, поскольку они по-прежнему эффективно «разбирают текст» даже в C ++ / CLI. Однако, когда они сталкиваются с дженериками с ограничениями, правила становятся намного жестче.