从构造函数参数推导出 std::set 的比较类型

Deduce type of Compare for std::set from constructor arguments

我想在使用自定义比较声明 std::set 时编写更简单的语法:

auto s = std::set({1,3,7,9,2,4},[](int a,int b){return a>b;});

但开箱即用。 CLang 产生:

/Users/kyb/devel/untitled3/main.cpp:13:14: error: ambiguous deduction for template arguments of 'set'
    auto s = set({1,3,7,9,2,4},[](int a,int b){return a>b;});
             ^
/Library/Developer/CommandLineTools/usr/include/c++/v1/set:531:5: note: candidate function [with _Key = int, _Compare = (lambda at /Users/kyb/devel/untitled3/main.cpp:13:32), _Allocator = std::__1::allocator<int>]
    set(initializer_list<value_type> __il, const value_compare& __comp = value_compare())
    ^
/Library/Developer/CommandLineTools/usr/include/c++/v1/set:547:5: note: candidate function [with _Key = int, _Compare = std::__1::less<int>, _Allocator = (lambda at /Users/kyb/devel/untitled3/main.cpp:13:32)]
    set(initializer_list<value_type> __il, const allocator_type& __a)
    ^
1 error generated.

还有一招-入侵推导:

namespace std::__1{
    template<typename T, typename Compare> set(initializer_list<T> il, const Compare&comp) -> set<T,Compare>;
}

产生警告:

warning: inline namespace reopened as a non-inline namespace

我相信有一种方法可以更简洁地做到这一点。

clang --version:

Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.7.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
/V/l/n/new-diag-commands ❯❯❯

I believe there is a way to do that in more clean way.

您上面的代码片段不应被 clang 拒绝,因为它受 [associative.reqmts]/151 [emphasis 我的约束] :

A deduction guide for an associative container shall not participate in overload resolution if any of the following are true:

  • (15.1) It has an InputIterator template parameter and a type that does not qualify as an input iterator is deduced for that parameter.
  • (15.2) It has an Allocator template parameter and a type that does not qualify as an allocator is deduced for that parameter.
  • (15.3) It has a Compare template parameter and a type that qualifies as an allocator is deduced for that parameter.

从 Clang 9 开始,这已得到纠正。


[1] N4659: March 2017 post-Kona working draft/C++17 DIS.