C ++ / CLI nullptr被错误地视为“int”

时间:2012-06-25 20:27:49

标签: c++-cli

我正在为第三方非托管库编写C ++ / CLI(VS2010)中的托管包装器。在代码中,我有一个如下所示的方法:

if(oldState != _state && UnitStateChanged != nullptr)
    UnitStateChanged(this, gcnew UnitStateChangedEventArgs(oldState, _state));

“nullptr”会生成以下错误:

  

错误C2446:'!=':没有从'int'转换为'UnitStateChangedEventHandler ^'

编译器似乎将“nullptr”用作“int”,即使是在这样简单的事情上:

Object^ temp = nullptr;

我读过的所有东西都表明编译器会自己解决它,但事实并非如此。是否有我缺少的设置(/ clr或#pragma托管除外)?

2 个答案:

答案 0 :(得分:3)

没有C ++ 11编译器的人写了

#define nullptr (0)

头文件中的某个地方?

(通常的宏是#define NULL (0)


当然,这是禁止的。

Standard section 17.6.4.3.1, forbidden using keywords as macro names list of C++11 keywords (Table 4 from the Standard)

答案 1 :(得分:2)

看起来你正在尝试解雇一个事件。

在C#中,有一个标准习惯用于触发事件,同时防止空引用异常和多线程修改:

// C#
EventHandler handler = this.MyEvent;
if(handler != null)
    handler(this, new EventArgs(foo));

看起来你正试图在C ++ / CLI中重新创建它,但这是不必要的。在C ++ / CLI中,一个事件将发出三个“内部方法”(它们的正确名称是什么?),称为addremoveraise。在C#中,它只创建addremove,没有显式加注,这就是我们必须反复编写该代码块的原因。

这是在C ++ / CLI中定义的事件,以及.NET Reflector在反编译时看到的内容:

// C++/CLI:
public ref class Test
{
public:
    event EventHandler^ MyEvent;
};


// Decompiled to C#:
public class Test
{
    // Fields
    private EventHandler <backing_store>MyEvent;

    // Events
    public event EventHandler MyEvent
    {
        [MethodImpl(MethodImplOptions.Synchronized)] add
        {
            this.<backing_store>MyEvent = (EventHandler) Delegate.Combine(this.<backing_store>MyEvent, value);
        }
        [MethodImpl(MethodImplOptions.Synchronized)] remove
        {
            this.<backing_store>MyEvent = (EventHandler) Delegate.Remove(this.<backing_store>MyEvent, value);
        }
        raise
        {
            EventHandler <tmp> = null;
            <tmp> = this.<backing_store>MyEvent;
            if (<tmp> != null)
            {
                <tmp>(value0, value1);
            }
        }
    }
}

raise内部方法正在为您执行空检查,因此您可以跳过此操作,只需触发事件而不进行检查。

if(oldState != _state)
    this->UnitStateChanged(this, gcnew UnitStateChangedEventArgs(oldState, _state));