模板运算符可见性,gcc vs clang

时间:2018-04-11 15:13:05

标签: c++ templates compiler-errors fold

我有这个代码,依赖于调用非常通用的比较运算符的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<实现?

0 个答案:

没有答案