std::sort 与本地类型比较

2024-01-24

下面的例子

// file mysort.cc
#include <string>
#include <vector>
#include <algorithm>
#include <string.h>

void mysort (const char**tab, unsigned size) {
  std::vector<int> vecix;
  vecix.resize(size);
  struct CompareIndex {
    const char**t;
    CompareIndex(const char**p) : t(p) {};
    bool operator() (int l, int r)  {
      return strcmp(t[l], t[r])<0;
    }
  };
  CompareIndex compix(tab);
  for (unsigned ix=0; ix<size; ix++) vecix[ix] = ix;
  std::stable_sort(vecix.begin(), vecix.end(), compix);
  std::vector<const char*> vecstr;
  vecstr.resize(size);
  for (unsigned ix=0; ix<size; ix++) vecstr[ix] = tab[vecix[ix]];
  for (unsigned ix=0; ix<size; ix++) tab[ix] = vecstr[ix];
}    

无法编译(在 C++03 标准的 Debian/Sid/x86-64 上使用 GCC 4.8.2)

mysort.cc: In function 'void mysort(const char**, unsigned int)':
mysort.cc:19:58: error: no matching function for call to 
      'stable_sort(std::vector<int>::iterator, 
                   std::vector<int>::iterator, 
                   mysort(const char**, unsigned int)::CompareIndex&)'
   std::stable_sort(vecix.begin(), vecix.end(), compix);
                                                      ^


In file included from /usr/include/c++/4.8/algorithm:62:0,
                 from mysort.cc:4:
/usr/include/c++/4.8/bits/stl_algo.h:5682:5: note: 
       template<class _RAIter, class _Compare>
                void std::stable_sort(_RAIter, _RAIter, _Compare)
     stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last,
     ^
/usr/include/c++/4.8/bits/stl_algo.h:5682:5: note:   
    template argument deduction/substitution failed:
mysort.cc: In substitution of 'template<class _RAIter, class _Compare>
     void std::stable_sort(_RAIter, _RAIter, _Compare)
     [with _RAIter = __gnu_cxx::__normal_iterator<int*, std::vector<int> >;
           _Compare = mysort(const char**, unsigned int)::CompareIndex]':
mysort.cc:19:58:   required from here
mysort.cc:19:58: error: template argument for
    'template<class _RAIter, class _Compare> 
         void std::stable_sort(_RAIter, _RAIter, _Compare)'
     uses local type 'mysort(const char**, unsigned int)::CompareIndex'
       std::stable_sort(vecix.begin(), vecix.end(), compix);
                                                          ^
mysort.cc:19:58: error:   trying to instantiate
            'template<class _RAIter, class _Compare>
                     void std::stable_sort(_RAIter, _RAIter, _Compare)'

以上内容是用GCC 4.8 http://gcc.gnu.org/gcc-4.8/ using

  g++ -Wall -c mysort.cc

我遇到了同样的错误

  g++ -std=c++03 -Wall -c mysort.cc

or with

  g++ -std=c++98 -Wall -c mysort.cc

但没有错误

  g++ -std=c++11 -c mysort.cc

鉴于我的g++ -v is a gcc version 4.8.2 (Debian 4.8.2-12)

但与铿锵/LLVM 3.4 http://llvm.org/releases/3.4/docs/ReleaseNotes.html编译用

  clang++ -Wall -c mysort.cc

我只收到警告:

  mysort.cc:19:7: warning: template argument uses local 
                  type 'CompareIndex'
                [-Wlocal-type-template-args]
  std::stable_sort(vecix.begin(), vecix.end(), compix);
  ^~~
  1 warning generated.

(并且在通过时我仍然只收到警告而不是错误-std=c++03 or -std=c++98 to clang++但没有警告clang++ -std=c++11)

所以我的问题是:为什么 GCC 会出现错误,而 Clang 会出现警告?我的代码合法并且没有未定义的行为(w.r.t. C++03 标准)吗?我应该让我的CompareIndex一个全球性的struct在我的编译单元中?

动机

当然,这是一种对 C 字符串数组进行排序的愚蠢方法。 真正的代码有点不同。事实上,我正在尝试使用std::stable_sort in my MELT http://gcc-melt.org/插件(用于扩展和自定义 GCC 的特定领域语言)。 MELT 正在生成 C++ 代码并具有copying 垃圾收集器 http://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29(因此指针由 GC 移动)。因此,我需要使用索引数组进行排序:比较函数实际上调用了 MELT 闭包(它可以在任意时刻触发复制 GC),因此我需要按索引(而不是原始指针)排序。我想让 MELT 生成的 C++ 代码符合编译 GCC 所需的 C++ 标准(03 或 98)。

解决方法

谢谢胡安乔潘萨的回答 https://stackoverflow.com/a/21201894/841108我通过移动声明解决了这个问题CompareIndex之前在全球范围内mysort.

I just committed the svn revision 206748 of the MELT branch of GCC; its file gcc/melt/warmelt-base.melt contains now a multiple_sort_new MELT function (to replace multiple_sort when it is working well) using std::stable_sort, and a global Melt_Sort_Compare_Index class in the generated C++ code.


C++03 中不允许使用局部类型作为模板参数。

根据 ISO/IEC 14882,14.3.1 模板类型参数 [temp.arg.type]:

本地类型、无链接的类型、未命名类型或类型 由任何这些类型合成的化合物不得用作 模板类型参数的模板参数。

给出的例子是这样的:

template <typename T> struct Foo {};

void foo()
{
  struct Bar {};
  Foo<Bar> b1;   // error: local type used as template-argument
  Foo<Bar*> x4;  // error: pointer to local type used as template-argument
}

C++11 中取消了此限制。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

std::sort 与本地类型比较 的相关文章

随机推荐

  • JPA。 JoinTable 和两个 JoinColumn

    我需要创建表 PORTATION MODEL SET 我需要从表 portation 创建两个密钥 从表phone model 创建一个密钥 我有代码 Entity Table name PORTATION SecondaryTable n
  • 为什么 Android Lint 在显式使用 Locale.US 时会警告 String.format 使用默认区域设置?

    我最初打电话String format这边走 return String format s f f anotherString doubleA doubleB 这使得 Android Lint 生成此警告 隐式使用默认区域设置是错误的常见来
  • 在 MongoDB 中,如何索引数组中的嵌入对象字段?

    多键的 mongodb 文档给出了查询数组中嵌入对象字段的示例 http www mongodb org display DOCS Multikeys http www mongodb org display DOCS Multikeys
  • 可垂直滚动的 GroupBox

    我正在使用创建一个应用程序Windows 申请表 我基本上是 C 和 Visual Studio 的新手 从昨天开始就一直在使用它 到目前为止 我已经成功创建了一个简单的表单 如屏幕截图所示 My Form 背景 细节 我正在使用框中提供的
  • 通过NotificationListenerService读取Google地图通知

    是否可以读取用户移动时定期显示的 Google 地图导航通知 例如 定期更新距下一回合的剩余距离 我尝试使用NotificationListenerService来实现此目的 但是当我尝试使用getNotifications getExtr
  • 使用react.js 在单页应用程序中导航

    我正在使用 React 和 Backbone 构建一个单页面应用程序 并试图找出处理应用程序中内容之间导航的最佳实践 我的应用程序将有一个侧边栏 其中包含链接 例如 照片 和 设置 侧边栏始终存在 因此单击 设置 后 我希望在不重新加载整个
  • TemporaryKey.pfx 出现问题 我没有密码

    我的一个客户有一个问题 他有一位 Microsoft CRM 开发人员 但他离开了 现在该项目仍未完成 我已经下载了自定义应用程序的源代码 并且我不想继续开发 我尝试过 ClickOne 部署 它会弹出一个与 myapp Temporary
  • ASP.NET Identity 2.1 将 PK 更改为 int 错误

    我已经按照中所述更改了 PKhttp www asp net identity overview extensibility change primary key for users in aspnet identity http www
  • 如何标记扩展宏(local :dir )?

    我知道我的标题令人困惑 因为tokenize命令被指定为一个字符串 我有许多文件夹 其中包含大量 独立的 命名不当的 Excel 文件 其中大部分是从网站上抓取的 手动选择不方便 需要依赖Stata扩展宏功能local dir阅读它们 我的
  • 如何像 Pinterest/Evernote 一样从 UICollectionView 过渡到 UIViewController

    我有一个 UICollectionView 当选择一个项目时 我希望它能够全屏显示动画 因此它会从单元格大小过渡到全屏并成为 UIViewController Pinterest 和 Evernote 都有这种行为 点击单元格会将单元格转换
  • jQuery 性能 - 按数据属性还是按类选择?

    哪个更快 为什么 选择 div 满足插件需求 div data something or div something 我倾向于前者 因为它 更干净 基于这个问题 https stackoverflow com questions 61795
  • Jquery - event.target 和 this 关键字之间的区别?

    有什么区别event target and this 假设我有 test click function e thisEventOb e target this this alert thisEventObj alert this 我知道警报
  • 您可以将 HTML 图像标签的 src 属性设置为控制器方法吗?

    我知道你可以做到这一点 img src http some svg on the web 但是如果我有一个带有注释的控制器方法怎么办 ResponseBody RequestMapping value getSVG public Respo
  • pygtk导入gtk错误

    我下载了中描述的所有内容 pygtk http www pygtk org 用于安装 一切都很顺利 直到我尝试打字 import gtk 它抛出了一个ImportError如下 from gtk import gtk ImportError
  • 如果进程被终止,写入 write() 的数据是否会刷新到磁盘?

    我正在使用一个程序qdbm http sourceforge net projects qdbm 维护键值存储 qdbm 链接到程序中 在某些情况下 该进程会在 qdbm 数据库中放入一个值 然后通过调用外部 init 脚本 通过 syst
  • Phonegap垂直滚动

    我正在为 ios 构建一个phonegap 应用程序 并且遇到垂直滚动问题 即使没有任何内容 网络视图中似乎也会有一些像素滚动 这会影响我在 html 中内置的绝对定位的导航栏和选项卡栏 这是我的 html 页面 没有内容 但我仍然得到图像
  • Promise 重试,直到使用 Typescript 成功/失败

    我的移动应用程序会连续将多个文件上传到服务器 这些文件通常来自连接强度有问题的偏远地区 为此 我想尝试几次发送文件 我还想在失败时继续尝试下一个 导出结束时显示所有错误消息 即 已上传 10 个文件 3 个失败 但是 我无法弄清楚带有承诺的
  • 两行Xerces程序中的异常

    下面的代码给了我一个例外XMLFormatTarget行 但如果我更改字符串 C test xml to test xml 效果很好 test cpp Defines the entry point for the console appl
  • 将引号之间的逗号替换为空格

    您好 我的表中每一行都有如下数据 0150566115 HEALTH 401K IC ON ICON HEALTH 401K 1 08 21 2014 我想要的是删除双引号 之间的每个逗号 然后用逗号 分割字符串的其余部分 我不想检查双引号
  • std::sort 与本地类型比较

    下面的例子 file mysort cc include