我有这个代码,依赖于调用非常通用的比较运算符的fold表达式:
#include <type_traits>
#include <vector>
#include <list>
template <typename Iter_a, typename Iter_b>
auto operator<(Iter_a, Iter_b) {
// original code makes more sense, I assure you
if constexpr ( std::is_same_v<Iter_a, Iter_b> ) {
return Iter_a();
}
else return Iter_b();
}
template <typename... Iterators>
using weakest_iterator = std::decay_t<decltype( (Iterators() < ...) )>;
int main() {
using lit = std::list<int>::iterator;
using vit = std::vector<int>::iterator;
using wi = weakest_iterator<lit, vit, float*>;
}
我对此代码有两个问题:
首先是g ++编译它并且clang ++(-std=gnu++2a
)拒绝这样做:
prog.cc:14:64: error: call to function 'operator<' that is neither visible in the template definition nor found by argument-dependent lookup
using weakest_iterator = std::decay_t<decltype( (Iterators() < ...) )>;
^
prog.cc:19:16: note: in instantiation of template type alias 'weakest_iterator' requested here
using wi = weakest_iterator<lit, vit, float*>;
^
prog.cc:6:6: note: 'operator<' should be declared prior to the call site
auto operator<(Iter_a, Iter_b) {
你知道为什么吗?我发现特别令人不安的是,clang在第19行的呼叫站点之前请求定义,它自己在第6行找到。
第二个是,如果我修改它以使用指针模板参数(using wi = weakest_iterator<int*, float*, float*>;
)调用我的元函数,我得到另一个错误消息,这次只用g ++,因为clang拒绝编译,我发现很难要真正明白:
main.cpp: In substitution of 'template<class ... Iterators> using weakest_iterator = std::decay_t<decltype ((Iterators() < ...))> [with Iterators = {int*, float*, float*}]':
main.cpp:19:57: required from here
main.cpp:14:75: error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
using weakest_iterator = std::decay_t<decltype( (Iterators() < ...) )>;
似乎1)operator<
的内置重载被调用(如果有这样的东西)超过我的超通用的,2)比较int*
和float*
被认为与比较指针和整数相同。
是否可以确保编译器选择了我自己的operator<
实现?