У меня есть этот код, опираясь на выражение сгиба, вызывающее очень общий оператор сравнения:
#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<
выбирается компилятором?
Задача ещё не решена.
Других решений пока нет …