【问题标题】:Contradiction in C++ standard?C ++标准中的矛盾?
【发布时间】:2011-05-13 08:05:47
【问题描述】:

std::map 必须满足第 23.1.2/2 段中指定的关联容器的要求:

每个关联容器都是 在 Key 和排序上参数化 导致严格的关系比较 元素的弱排序(25.3) 钥匙。此外,地图和多地图 将任意类型 T 与 钥匙。比较类型的对象是 称为a的比较对象 容器。这个比较对象可能 成为函数指针或对象 具有适当功能的类型 呼叫接线员。

但是在第 23.3.1/2 段中,std::map 模板被指定为:

template <class Key, class T, class Compare = less<Key>,
          class Allocator = allocator<pair<const Key, T> > >
class map;

这似乎明确禁止将函数指针用作Compare。这是矛盾还是我没有正确理解标准?

编辑:是的,我真正遇到的问题是为什么像 GMan 的示例这样的代码:

struct foo
{
    int x;
};

bool compare_foo(const foo& x, const foo& y)
{
    return x.x < y.x;
}

std::map<foo, bool, compare_foo> fooMap;

不会编译(是的,我愚蠢地混淆了Compare 参数的类型和值)。

【问题讨论】:

  • 如果您解释为什么您认为这以某种方式“明确禁止使用函数指针”,我们将能够更好地回答。
  • 下一次,如果您只是学习使用该语言,也许不要去阅读规范。 Use a tutorial

标签: c++


【解决方案1】:

Compare 是比较器的类型。使用class 而不是typename 声明它的事实并没有什么区别,您可以将函数指针作为类型并在映射构造函数中给出您的函数。

#include <map>

bool myCmp(int a, int b) {
    return a < b;
}

void foo()
{
    std::map<int, char*, bool (*)(int, int)> m(myCmp);
}

【讨论】:

    【解决方案2】:

    这个:

    class Compare
    

    并不意味着 Compare 必须是一个类。如果这样说可能会更清楚:

    typename Compare
    

    您可以使用任何提供类似函数调用语义的类型,例如函数指针。

    【讨论】:

    • 除了安德烈亚斯想说他仍然很困惑。事实证明,真正的问题是为什么他的代码无法编译,而不是类这个词的含义。和往常一样,我们需要先找到真正的问题:)
    【解决方案3】:

    这样指定:

    struct foo
    {
        int x;
    };
    
    bool compare_foo(foo x, foo y)
    {
        return x.x < y.x;
    }
    
    //                  vvvvvvvvvvvvvvvvv function pointer type
    std::map<foo, bool, bool(*)(foo, foo)> fooMap(compare_foo);
    //                     function pointer value ^^^^^^^^^^^
    

    【讨论】:

    • 是的,但是以 Compare 为前缀的 class 似乎无法指定函数指针
    • 当我尝试用 MSVC10 编译它时,我得到 error C2923: 'std::map' : 'compare_foo' is not a valid template type argument for parameter '_Pr'
    • 科莫给error: function "compare_foo" is not a type name std::map&lt;foo, bool, compare_foo&gt; fooMap;
    • 试试:std::map&lt;foo, bool, bool(*)(const foo&amp; x, const foo&amp; y)&gt; fooMap(&amp;compare_foo);
    • @Andreas:哦,对不起。您并没有真正说明 为什么 您认为这是矛盾的,我假设您认为 =meant 要求或其他东西。您应该将其添加到您的问题中。 class 只是模板规范中具有某种语义的关键字,与typename 没有任何不同。是的,我犯了一个愚蠢的错误,请允许我改正它。
    【解决方案4】:

    您混淆了比较器的类型和值;使用这个例如:

    int main()
    {
        std::map<foo, bool, bool(*)(const foo&, const foo&)> fooMap(compare_foo);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-05
      • 2016-10-06
      • 2017-11-06
      • 2012-08-23
      • 1970-01-01
      • 2021-07-13
      • 2017-09-30
      相关资源
      最近更新 更多