Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Templates 为什么可以';t我创建System::Collections::Generic::IEnumerable的模板化子类<;T>;? < >我想创建一个通用的IQueDebug实现,以便更容易封装一些本地C++类。当我尝试使用模板参数作为IEnumerable的参数来创建实现时,我得到了一个错误_Templates_Generics_C++ Cli - Fatal编程技术网

Templates 为什么可以';t我创建System::Collections::Generic::IEnumerable的模板化子类<;T>;? < >我想创建一个通用的IQueDebug实现,以便更容易封装一些本地C++类。当我尝试使用模板参数作为IEnumerable的参数来创建实现时,我得到了一个错误

Templates 为什么可以';t我创建System::Collections::Generic::IEnumerable的模板化子类<;T>;? < >我想创建一个通用的IQueDebug实现,以便更容易封装一些本地C++类。当我尝试使用模板参数作为IEnumerable的参数来创建实现时,我得到了一个错误,templates,generics,c++-cli,Templates,Generics,C++ Cli,下面是我提出的一个简单版本,它说明了我的问题: ref class A {}; template<class B> ref class Test : public System::Collections::Generic::IEnumerable<B^> // error C3225... {}; void test() { Test<A> ^a = gcnew Test<A>(); } ref类A{}; 模板 ref类测试:公共系统

下面是我提出的一个简单版本,它说明了我的问题:

ref class A {};

template<class B>
ref class Test : public System::Collections::Generic::IEnumerable<B^> // error C3225...
{};

void test()
{
    Test<A> ^a = gcnew Test<A>();
}
ref类A{};
模板
ref类测试:公共系统::集合::泛型::IEnumerable//错误C3225。。。
{};
无效测试()
{
测试^a=gcnew测试();
}
在指示的行中,我得到以下错误:

错误C3225:“T”的泛型类型参数不能是“B^”,它必须是值类型或引用类型的句柄

如果我使用不同的父类,我看不出问题:

template<class P>
ref class Parent {};

ref class A {};

template<class B>
ref class Test : public Parent<B^> // no problem here
{};

void test()
{
    Test<A> ^a = gcnew Test<A>();
}
模板
ref类父{};
ref类A{};
模板
ref类测试:公共父级//这里没有问题
{};
无效测试()
{
测试^a=gcnew测试();
}
我可以通过向实现类型添加另一个模板参数来解决此问题:

ref class A {};

template<class B, class Enumerable>
ref class Test : public Enumerable
{};

void test()
{
    using namespace System::Collections::Generic;
    Test<A, IEnumerable<A^>> ^a = gcnew Test<A, IEnumerable<A^>>();
}
ref类A{};
模板
ref类测试:公共可枚举
{};
无效测试()
{
使用命名空间System::Collections::Generic;
测试^a=gcnew测试();
}

但这对我来说似乎很混乱。另外,我想了解一下这里发生了什么-为什么第一种方法不起作用?

在第一个示例中,您的继承行应该是:

ref class Test : public System::Collections::Generic::IEnumerable<B>
Test<A^> ^a = gcnew Test<A^>();
ref类测试:公共系统::集合::通用::IEnumerable
(模板上没有参考标记)

那么您的用法行应该是:

ref class Test : public System::Collections::Generic::IEnumerable<B>
Test<A^> ^a = gcnew Test<A^>();
Test^a=gcnewtest();
引用标记位于模板的实例化中,而不是模板本身

这是您的示例,可编译:

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^>();
}
使用名称空间系统;
使用命名空间System::Collections::Generic;
ref类A{};
模板引用类测试:公共系统::集合::泛型::IEnumerable
{
公众:
B GetInstance()
{
返回激活器::CreateInstance();
}
虚拟系统::集合::IEnumerator^GetEnumeratorObj()=
系统::集合::IEnumerable::GetEnumerator
{
返回空ptr;
}
虚拟系统::集合::泛型::IEnumerator^GetEnumerator()
{
返回空ptr;
}
};
无效测试()
{
测试^a=gcnew测试();
}

编辑:意识到我应该解释这是为什么。据我所知,不能在IEnumerable继承中指定B^的原因是IEnumerable是一个带有约束的泛型,而B是一个不受约束的模板参数。模板允许更灵活的语法,即使在它们管理ref对象时也是如此,因为即使在C++/CLI中,它们仍然是有效的“解析文本”。然而,当他们遇到带有约束的泛型时,规则会变得更加严格。

谢谢,这解决了最初的问题。不过,我遗漏了部分问题——我还想在测试类中创建B的新实例。对于您的解决方案,gcnew B()会失败,因为B是一种句柄类型,有办法解决吗?是的,尽管这一点都不直观。使用激活器::CreateInstance()。我更新了上面的示例以进行演示。