Сужение концепции C ++ для исключения определенных типов - PullRequest
0 голосов
/ 27 февраля 2019

Предположим, я бы хотел перегрузить левый оператор сдвига для ostream s и всех контейнеров.

Это то, что у меня сейчас (скомпилировать с -fconcepts):

#include <vector>
#include <iostream>

template<typename Container>
concept bool Iterable = requires(Container t) {
        { *t.begin()++, t.end() };
};

template<Iterable T>
std::ostream& operator<<(std::ostream& out, const T& t) {
    for(const auto& it: t) {
        out << it << " " ;
    }
    return out;
}

int main() {
    std::vector<int> a = {1, 2, 3};
    std::cout << a << std::endl;

    std::string str = "something";
    // std::cout << str << std::endl; // compile error if the template is defined
    return 0;
}

Проблема, однако, заключается в том, что это уже есть версия ostream&<< для std::string.

Существует ли общее (что-то вроде requires not выражение) или конкретное (возможно, похожее начастичная специализация, с помощью которой я могу исключить конкретные классы) способ исключить что-либо в понятии?

Если нет, как правильно это обойти?

1 Ответ

0 голосов
/ 27 февраля 2019
template<Iterable T>
    requires !requires(std::ostream o, T a) { operator<<(o, a); }
std::ostream& operator<<(std::ostream& out, const T& t) {
    for(const auto& it: t) {
        out << it << " " ;
    }
    return out;
}

Добавьте требование, чтобы тип еще не определил operator<<.Я не уверен на 100%, что это должно работать, но оно работает на gcc .

(просто o << a вылетает gcc)

...