【问题标题】:Why I cannot pass a constant to String.Contains() in C++/CLI?为什么我不能在 C++/CLI 中将常量传递给 String.Contains()?
【发布时间】:2014-04-02 07:06:11
【问题描述】:

我观察到 System.Contains() Method! 在 C# 和 C++/CLI 中的不同行为!

让我们看一下 C# 示例,

string s1 = "The quick brown fox jumps over the lazy dog";
string s2 = "fox";
bool b;
b = s1.Contains(s2)

由于我认为不应该更改 s2,所以我将其设为 const string s2 = "fox"; 的常量,并且程序运行没有任何问题。


现在转向 C++/CLI 示例,
String^ s1 = "The quick brown fox jumps over the lazy dog";
String^ s2 = "fox";
bool b;
b = s1->Contains( s2 );

当我将 s2 转为 const String^ s2 = "fox"; 时,编译返回错误 C2664 - 无法将参数 1 从 const System::String ^ 转换为 System::String ^


我知道在 C# 中,三个重载函数之一是bool string.Contains(string value)。它接受一个常量输入作为函数参数。然而在 C++/CLI 中,函数是 bool System::String::Contains(System::String ^ value)。这两个函数在我看来都一样,但第二个函数却出乎我的意料。

这是为什么呢?如何在 C++/CLI 中将常量传递给 Contains()?我经常使用 C++ 和 C# 进行编程,但对 C++/CLI 来说是新手。

谢谢。

【问题讨论】:

  • 您在传递参数时是否尝试过类型转换为System::String ^

标签: c# .net c++-cli parameter-passing constants


【解决方案1】:

const 关键字是特定于 C++ 的,仅在 C++/CLI 中受到较弱的支持。您可以在自己的声明中使用它,但只有 C++/CLI 编译器可以强制执行它。 CLR 和 .NET Framework 类都不了解它,这在其他语言(包括 C#)中效果不佳。

请注意,String 已经是不可变的,因此添加 const 并不会为您带来更多好处。当然支持传递字符串文字。

您可能会对不同的关键字感到困惑。 C++/CLI 有 initonly 关键字,其工作方式与 C# 中的 readonly 相同。 C# const 关键字在 C++/CLI 中是 literal

public ref class Example{
public:
    literal String^ constantString = "foo";   // Same as const in C#
    initonly String^ readonlyString = "bar";  // Same as readonly in C#
    // etc...
};

并且工作方式与它们在 C# 中的工作方式相同。 literal 直接替换在生成的代码中,它只能出现在类声明中。应避免使用公共文字,除非它们是明显的常量(如 Math::Pi)。 initonly 变量防止修改引用,而不是对象本身。但 String 不是问题,因为它已经是不可变的。

【讨论】:

  • 谢谢我犯了同样的错误。就我而言,将内容传递给另一个函数后出现问题,除非将值复制到另一个字符串中。
【解决方案2】:

我知道在 C# 中,三个重载函数之一是 bool string.Contains(string value)。它接受一个常量输入作为函数参数

不,它接受对字符串对象的引用。合同中没有提到“常数”。

CLR 不支持 C++ 意义上的 const。 (因为大多数 .NET 语言不这样做,而且 CLR 必须坚持一个通用子集,该子集可以用所有构建在它之上的语言来表达)。

类库中的所有函数都是在未指定 const 的情况下定义的,因此您的 C++(或 C++/CLI)代码也必须丢弃 const。该函数采用对字符串的托管引用——而不是对 const 字符串的托管引用。因为这就是 CLR 函数的定义方式。

【讨论】:

    【解决方案3】:

    当您将const 添加到某个变量时,您会添加一些限制。如果您不打算修改它,通常标记函数参数const。但是,您不能在期望更少限制的情况下传递具有更多限制的参数。我认为,在这种特殊情况下,const 可能被完全错误地省略了。

    如果您将参数类型转换为System::String ^,这应该可以解决您的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-04
      • 1970-01-01
      • 1970-01-01
      • 2013-06-25
      • 1970-01-01
      • 2016-08-16
      • 2011-02-05
      相关资源
      最近更新 更多