Platform :: Collections :: Map - 以enum为关键

时间:2012-08-25 10:15:10

标签: windows-8 windows-runtime c++-cx

我是一个尝试进入c ++的c#dev,我正在编写一些自定义控件。 我需要以下复杂的c#Dictionary

的c ++等价物
private static Dictionary<PinchscapeColor, 
        Dictionary<PinchscapeColorLevel, Brush>> AccentColorMap;

PinchscapeColor和PinchscapeColorLevel是简单的c#enums

public enum PinchscapeColorLevel
{
    Light,
    Medium
    Dark
}

public enum PinchscapeColor
{
    PinchscapeCyan,
    PinchscapeLime,
    PinchscapeMagenta,
    PinchscapeTangerine,
    PinchscapePlum
}

我计算一个特定的颜色/颜色级别组合(在c#中)

var color = AccentColorMap[PinchscapeColor.PinchscapeCyan][PinchscapeColorLevel.Dark];

我在c ++中尝试这样做的尝试已经成功了:

我的枚举:

public enum class PinchscapeColorLevel
{
    Light,
    Medium,
    Dark
};

public enum class PinchscapeColor
{
    PinchscapeCyan,
    PinchscapeLime,
    PinchscapeMagenta,
    PinchscapeTangerine,
    PinchscapePlum
};

我已经在我的头文件中定义了一个这样的地图

Platform::Collections::Map<PinchscapeBasicControls::PinchscapeColor,
    Platform::Collections::Map<PinchscapeBasicControls::PinchscapeColorLevel,
    Windows::UI::Xaml::Media::Brush^>^>^ colorMap;

但我得到以下编译器错误:

程序文件(x86)\ microsoft visual studio 11.0 \ vc \ include \ collection.h(1118):错误C3986:'调用':公共成员的签名包含本机类型'std :: less&lt; _Ty&gt;' (这是第一行,它会永远持续下去)

有没有人有任何想法我做错了什么?我想象这会很容易:(

修改

请在下面找到一个最小代码示例,它是复制问题所需的所有代码:

1)Class1.h

#pragma once

namespace WindowsRuntimeComponent1
{
    public enum class ColorLevelEnum
    {
        Light,
        Medium,
        Dark
    };

    public enum class ColorEnum
    {
        Cyan,
        Lime,
        Magenta,
        Tangerine,
        Plum
    };

    public ref class Class1 sealed
    {
    private:
        Windows::Foundation::Collections::IMap<WindowsRuntimeComponent1::
            ColorEnum,Windows::Foundation::Collections::IMap<WindowsRuntimeComponent1::
            ColorLevelEnum,Windows::UI::Xaml::Media::Brush^>^>^ colorMap;
    public:
        Class1();
    };
}

Class1.cpp

#include "pch.h"
#include <collection.h>
#include "Class1.h"

using namespace WindowsRuntimeComponent1;
using namespace Windows::UI::Xaml::Media;
using namespace Platform::Collections;
using namespace Platform;

Class1::Class1()
{
    if (colorMap == nullptr)
    {
        colorMap = ref new Map<ColorEnum,Map<ColorLevelEnum,Brush^>^>();
    }
}

希望能帮助您重新创建问题

感谢任何花时间帮助我解决问题的人

1 个答案:

答案 0 :(得分:1)

问题中显示的代码格式正确,使用Visual Studio 2012的RTM版本可以正确编译。

我可以推测,问题的原因是:您可能使用此colorMap(或其类型)作为公共ref class的公共或受保护成员或你以某种方式使用它,它的类型最终是公共或受保护成员的类型。

Platform::Collections::Map类型是接口Windows::Foundation::Collections::IMap的特定于C ++ / CX的实现。声明Windows运行时类型的公共成员时,需要使用IMap,而不是Map,因为Map依赖于C ++ - 以及不可用的C ++ / CX特定语言功能Windows运行时ABI。

简而言之,如果您将colorMap更改为使用IMap,则应解决问题:

IMap<
    PinchscapeColor,
    IMap<
        PinchscapeColorLevel,
        Brush^
    >^
>^ colorMap;

当您实例化时,您需要先使用Platform::Collections::Map实例化外部地图,然后再实例化每个内部地图。例如:

// Create the outer map; note the "value type" is still IMap<T, U>
colorMap = ref new Map<ColorEnum,IMap<ColorLevelEnum,Brush^>^>();

// Insert an element into the outer map:
colorMap->Insert(ColorEnum::Cyan, ref new Map<ColorLevelEnum, Brush^>());

考虑使用一些typedef来使代码更清晰:

typedef IMap<PinchscapeColorLevel, Brush^>          IColorLevelBrushMap;
typedef IMap<PinchscapeColor, IColorLevelBrushMap^> IColorMap;

IColorMap^ colorMap;

或者,如果您不需要让其他Windows运行时组件可以访问此地图,请考虑使用std::map,这将显着改善:

typedef std::map<PinchscapeColorLevel, Brush^>        ColorLevelBrushMap;
typedef std::map<PinchscapeColor, ColorLevelBrushMap> ColorMap;

ColorMap colorMap;

或者:

typedef std::pair<PinchscapeColor, PinchscapeColorLevel> ColorMapKey;
typedef std::map<ColorMapKey, Brush^>                    ColorMap;

ColorMap colorMap;