Reputation: 624
The C++ concepts are a relatively new idea in C++. But we have few available explanation as to how it works.
struct contain {
public:
using Tin = int;
using Tout = int;
Tout sqr(Tin x)
{
return x * x;
}
contain(int _x) : x(_x)
{
}
int get_x() const
{
return x;
}
private:
int x;
};
int cube(contain u)
{
int x = u.get_x();
return x * x * x;
}
That is we want to have a concept that tests that contain contains Tin, Tout and a member function Tout sqr(Tin). Would it also be possible to test if there is a non-member function cube(contain)?
Upvotes: 0
Views: 165
Reputation: 170064
That is we want to have a concept that tests that contain contains
Tin
,Tout
and a member functionTout sqr(Tin)
. Would it also be possible to test if there is a non-member function cube(contain)?
It kinda depends on what you mean by that. You can of course write a concept for something that behaves "enough like" contain
:
#include <concepts>
template<class C>
concept ContainLike = requires(C c, typename C::Tin in) // typename only needed for Clang, until it implements P0634
{
{ c.sqr(in) } -> std::same_as<typename C::Tout>;
cube(c);
};
The concept checks for a type C
, that when given two hypothetical objects of type C
and C::Tin
, a list of explicit constraints holds:
c.sqr(in)
is well-formed and returns C::Tout
.cube(c)
is well-formed (can be found by ADL in our case). The type of the expression isn't constrained here.Note that the test for C::Tout
and C::Tin
is implicit here. If C
doesn't contain those types, it will be a substitution failure, which will make the concept not be satisfied (in a SFINAE friendly way).
Another thing worth mentioning is that this doesn't check C
contains a sqr
method whose parameter is a Tin
. Rather it checks that a Tin
may be passed as an argument (which may entail conversions to the actual parameter type). This is the more natural use of concepts: duck typing.
Upvotes: 2