为什么从我的 class 外部调用它时会出现转换错误?
Why do I get a conversion error when calling this from outside my class?
我有一个 class 我正在尝试为其编写一些单元测试,但我遇到了转换错误:
1>c:\projects\myproj\unittests\UnitTest_MyClass.h(60): error C2664: 'MyClass::MyFunc' : cannot convert parameter 1 from 'GenericCollections::CircularBuffer<T> ^' to 'GenericCollections::CircularBuffer<T> ^'
1> with
1> [
1> T=const MyProj::DataPacket ^
1> ]
1> and
1> [
1> T=MyProj::DataPacket ^const
1> ]
Class 正在测试中(只是一个片段):
public ref class MyClass
{
protected:
double MyFunc(GenericCollections::CircularBuffer<const MyProj::DataPacket^>^ data, int &firstIndex, int &lastIndex);
单元测试(只是一个片段):
[Test]
public ref class UnitTest_MyClass : public MyClass
{
public:
[Test]
void Test_0001_MyFunc()
{
GenericCollections::CircularBuffer<const MyProj::DataPacket^>^ data = nullptr; // This will eventually be populated with test data
int firstIndex = 0;
int lastIndex = data->Length-1;
double funcResult = MyFunc(data, firstIndex, lastIndex); // causes error C2664
}
我可以在测试中的 class 中以相同的方式调用此方法并且它工作正常,那么为什么当我从单元测试中调用它时它会失败?
with
[
T=const Anchor::DataPacket ^
]
and
[
T=Anchor::DataPacket ^const
]
看起来编译器混淆了对 const 对象的引用和对对象的 const 引用。 C2664 的错误描述页面没有显式显示传递 const 引用集合时发生的情况。我想我会尝试从模板中删除常量。
问题中缺少一个重要的细节,但可以推断出来。这无法编译,因为您正在通过程序集引用而不是#include 导入类型定义。您对该代码进行单元测试的预期方式。
您必须记住 const
关键字是一个问题,CLR 完全忽略了这个概念。它只有在强制执行时才有意义,当您的代码被另一种托管语言(如 VB.NET 或 C#)使用时,这种情况不会发生。没有任何类似于 const
它在本机 C++ 中的使用方式的语言。
CLR 中的元数据确实允许语言通过 [modopt] 构造向变量和参数类型添加任意属性。 C++/CLI 编译器在发出 Func<> 的元数据时使用它,您可以通过 ildasm.exe:
看到它
MyFunc(class GenericCollections.CircularBuffer`1<
class DataPacket modopt([mscorlib]System.Runtime.CompilerServices.IsConst)
> data,
// etc...
编辑以适合,注意类型参数上发出的 [modopt]。然而,这还不足以完全表达 const 可以在本机 C++ 中应用的各种方式。 data 参数可以是 const T^ data
、T^ data const
或 const T^ data const
。不是一个 [modopt].
可以表达的东西
您可能会争辩说这是编译器缺陷,但事实并非如此,此限制是故意的。他们确实让编译器足够聪明,可以注意到 const
在这里有歧义,并生成适当的错误消息。
好吧,对此您无能为力。当您#include 类型定义时,这将不是问题,编译器随后就足够了解声明。也许你可以重新调整你的项目,尽管它不是很实用。对于这个问题,我通常的建议是放弃 const
在托管代码中有用的想法。事实并非如此,C++/CLI 是一种互操作语言,这种代码的普通使用者不了解有关 const 的 bean,因此不会强制执行它。
我有一个 class 我正在尝试为其编写一些单元测试,但我遇到了转换错误:
1>c:\projects\myproj\unittests\UnitTest_MyClass.h(60): error C2664: 'MyClass::MyFunc' : cannot convert parameter 1 from 'GenericCollections::CircularBuffer<T> ^' to 'GenericCollections::CircularBuffer<T> ^'
1> with
1> [
1> T=const MyProj::DataPacket ^
1> ]
1> and
1> [
1> T=MyProj::DataPacket ^const
1> ]
Class 正在测试中(只是一个片段):
public ref class MyClass
{
protected:
double MyFunc(GenericCollections::CircularBuffer<const MyProj::DataPacket^>^ data, int &firstIndex, int &lastIndex);
单元测试(只是一个片段):
[Test]
public ref class UnitTest_MyClass : public MyClass
{
public:
[Test]
void Test_0001_MyFunc()
{
GenericCollections::CircularBuffer<const MyProj::DataPacket^>^ data = nullptr; // This will eventually be populated with test data
int firstIndex = 0;
int lastIndex = data->Length-1;
double funcResult = MyFunc(data, firstIndex, lastIndex); // causes error C2664
}
我可以在测试中的 class 中以相同的方式调用此方法并且它工作正常,那么为什么当我从单元测试中调用它时它会失败?
with
[
T=const Anchor::DataPacket ^
]
and
[
T=Anchor::DataPacket ^const
]
看起来编译器混淆了对 const 对象的引用和对对象的 const 引用。 C2664 的错误描述页面没有显式显示传递 const 引用集合时发生的情况。我想我会尝试从模板中删除常量。
问题中缺少一个重要的细节,但可以推断出来。这无法编译,因为您正在通过程序集引用而不是#include 导入类型定义。您对该代码进行单元测试的预期方式。
您必须记住 const
关键字是一个问题,CLR 完全忽略了这个概念。它只有在强制执行时才有意义,当您的代码被另一种托管语言(如 VB.NET 或 C#)使用时,这种情况不会发生。没有任何类似于 const
它在本机 C++ 中的使用方式的语言。
CLR 中的元数据确实允许语言通过 [modopt] 构造向变量和参数类型添加任意属性。 C++/CLI 编译器在发出 Func<> 的元数据时使用它,您可以通过 ildasm.exe:
看到它 MyFunc(class GenericCollections.CircularBuffer`1<
class DataPacket modopt([mscorlib]System.Runtime.CompilerServices.IsConst)
> data,
// etc...
编辑以适合,注意类型参数上发出的 [modopt]。然而,这还不足以完全表达 const 可以在本机 C++ 中应用的各种方式。 data 参数可以是 const T^ data
、T^ data const
或 const T^ data const
。不是一个 [modopt].
您可能会争辩说这是编译器缺陷,但事实并非如此,此限制是故意的。他们确实让编译器足够聪明,可以注意到 const
在这里有歧义,并生成适当的错误消息。
好吧,对此您无能为力。当您#include 类型定义时,这将不是问题,编译器随后就足够了解声明。也许你可以重新调整你的项目,尽管它不是很实用。对于这个问题,我通常的建议是放弃 const
在托管代码中有用的想法。事实并非如此,C++/CLI 是一种互操作语言,这种代码的普通使用者不了解有关 const 的 bean,因此不会强制执行它。