C ++ / CLI语法澄清

时间:2013-01-30 17:21:30

标签: c++-cli

在查看marshal_as时,其中一个函数调用需要以下格式:

System::String^ const &

托管指针之后const &的目的是什么?

这不能为我编译:

static std::wstring GetString(const System::String^ value)
{
    return msclr::interop::marshal_as<std::wstring>(value);
}

错误1错误C4996:

'msclr :: interop :: error_reporting_helper&lt; _To_Type,_From_Type&gt; :: marshal_as':库不支持此转换,或者不包含此转换所需的头文件。有关添加自己的编组方法的信息,请参阅“如何:扩展封送库”的文档。 c:\ program files(x86)\ microsoft visual studio 9.0 \ vc \ include \ msclr \ marshal.h 203

这样做:

static std::wstring GetString(const System::String^ value)
{
    return msclr::interop::marshal_as<std::wstring>(const_cast<System::String^>(value));
}

1 个答案:

答案 0 :(得分:3)

marshal_as方法由此模板定义:

template <class _To_Type, class _From_Type>
inline _To_Type marshal_as(const _From_Type&);

额外const &的主要目的是符合此模板声明。

这确实会影响函数的调用方式:我检查了IL,String^作为const间接引用传递,正如人们所期望的那样,但这并不是一个重大改变。

如果该方法是独立的,它可能会在没有const &的情况下声明,并且几乎没有区别。


您尝试使用String^ const &调用方法String^ const。编译器无法自动(安全地)进行转换。

您对const_cast的操作是将String^ const变为常规String^。编译器可以安全自动地将String^转换为String^ const &

我只是从本地方法声明中删除const。这为我编译:

static std::wstring GetString(System::String^ value)
{
    return msclr::interop::marshal_as<std::wstring>(value);
}

为什么编译器不能进行转换?请注意,String^ const &const String^ const &不是一回事。第一个说“指向字符串对象的常量指针”。第二个说“指向常量字符串对象的常量指针”。在使用(const System::String^ value)的方法中,你有一个常量字符串对象,而你正在调用的函数需要一个指向非const字符串对象的指针。我们知道String类是不可变的,但是编译器没有,因此它不会将地址传递给const对象,而是认为该对象是非const的方法。

(我使用的是Visual Studio 2010 SP1,但我不认为编组方法在2008年到2010年间有任何重大变化。)