Могу ли я правильно использовать концепции C ++ 20 в объявлении об использовании? - PullRequest
3 голосов
/ 30 октября 2019

Я немного поигрался с Концепциями, предлагаемыми в C ++ 20, и придумал простой пример, который, к моему удивлению, не дает ожидаемых результатов (пожалуйста, оставьте обсуждение наполезность моего примера: -)):

#include <iostream>
#include <type_traits>
#include <vector>

template <typename T>
concept i_am_integral = requires { std::is_integral_v<T> == true; };

template <typename T> requires i_am_integral<T>
using intvector = std::vector<T>;

int main() {
    intvector<int> v = { 1, 2, 3 }; // <- This is fine, int is an integral type

    // I would expect this to fail:
    intvector<double> w = { 1.1, 2.2, 3.3 };

    // I'm curious, so let's print the vector
    for (auto x : w) { std::cout << x << '\n'; }

    // Same here - IMO, this should fail:
    struct S{};
    intvector<S> s;
}

Я пытался сделать intvector «ограниченным» std::vector, который может принимать только целочисленные типы. Тем не менее, intvector, кажется, поглощает произвольные типы точно так же, как и исходный вектор, включая определяемые пользователем типы.

Это моя ошибка, или Clang еще недостаточно стабилен для правильной обработки этого случая? Я подозреваю, что есть проблема в смешивании псевдонимов и требований типов (как указано в этот ответ ), но я не могу понять это - в частности, мой пример компилируется, в то время как тот, что в ссылочном посте не 'т.

1 Ответ

6 голосов
/ 30 октября 2019

Ваша концепция:

template <typename T>
concept i_am_integral = requires { std::is_integral_v<T> == true; };

не проверяет, является ли тип целым. Вместо этого он проверяет, возможно ли сравнение std::is_integral_v<T> с true (что всегда возможно). Чтобы исправить свой код, вы должны просто сделать:

template <typename T>
concept i_am_integral = std::is_integral_v<T>;
...