I'm trying to study the concept functionality and syntax, but I failed to come up with a working example of std::vector, any idea of what is going wrong? https://gcc.godbolt.org/z/FHaQ-3
#include <vector>
#include <string>
template<typename T>
concept Compare = requires(T a, T b) {
{ a <=> b } -> std::same_as<std::partial_ordering>;
};
struct Cat {
int age;
std::string name;
auto operator<=>(const Cat&) const = default;
};
int main(int argc, char** argv) {
/* Single type: Fail
std::vector<Compare auto> vec{
Cat{4, "Faisca"},
Cat{4, "Neka"}
};
*/
/* Heterogenous: Fail
std::vector<Compare auto> vec{
Cat{4, "Faisca"}, 1, std::string{"Deu Ruim"}
};
*/
return 0;
}
You can't have a std::vector
of heterogenous types.
However, you can have a std::vector
of type T
that satisfies a concept. Simply provide a alias template that is constrained:
template<typename T>
requires Compare<T>
using vec = std::vector<T>;
or with terse syntax:
template<Compare T>
using vec = std::vector<T>;
Now, you can do:
vec<Cat> v;
but not
vec<int> v;
Note that your Cat
class as currently written, doesn't actually satisfy the concept Compare
. If you change the return type of operator<=>
, like this:
std::partial_ordering operator<=>(const Cat&) const = default;
you can create a vector of Cat
s:
vec<Cat> a{
Cat{4, "Faisca"},
Cat{4, "Neka"}
};
You cannot use placeholder types ( auto
and decltype(auto)
, with or without constraints) within template argument lists like that. You must either use a concrete type or rely on class template argument deduction from C++17 (by not specifying template arguments at all).
A vector<T>
is a sequence container, and sequence containers contain objects of a given type. A single given type.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.