3 ms·
template<typename T> concept has_foo = requires(T x){ { x.foo } -> std::same_as<int>; }; template<has_foo T> int get_foo(T x){...} // or templa
by siknad 4y ago
template<typename T>
concept has_foo = requires(T x){
{ x.foo } -> std::same_as<int>;
};
template<has_foo T>
int get_foo(T x){...}
// or
template<typename T>
requires has_foo<T>
void f(T x){...}
// or even
void f(has_foo auto x) {...}
- BobbyJo 4y agoDoes the above provide more safety/guarantees/something than just: type hasFoo interface { getfoo() int setfoo(int) } func f(hasFoo) {} ?
- BenFrantzDale 4y agoI don’t know Go, but I think less in that concepts are syntax guarantees, not semantic guarantees. I suspect interfaces (assuming they are opt-in) are semantic guarantees. That said, I’ve never run into this distinction being a problem, and you could provide opt-in mechanisms in C++. Of course, the C++ interface has zero runtime cost.
- throwaway894345 4y agoThe equivalent Go would be something like: func f[T interface{.Foo}](T) {} Of course, this doesn't exist in Go, so we must do: func f[T interface{GetFoo(); SetFoo()}](T) {} And then define setters and getters on every type we want to use, including defining new types (with the commensurate setters/getters) for types that we don't own (i.e., if you import a struct from another package and it doesn't have setters and getters defined, you have to create a new type that implements those setters/getters).