从构造函数参数推导出 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 开始,这已得到纠正。
我想在使用自定义比较声明 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 开始,这已得到纠正。