Do C++ Concepts allow for my class at declaration/definition to specify it satisfies certain concept?
Asked Answered
P

2

14

Currently best way I can think of is to use static_assert, but I would prefer nicer way.

#include <set>
#include <forward_list>

using namespace std;

template<typename C>
concept bool SizedContainer = requires (C c){
    c.begin();
    c.end();
    {c.size()} -> size_t;
};

static_assert(SizedContainer<std::set<int>>);
static_assert(!SizedContainer<std::forward_list<int>>);
static_assert(!SizedContainer<float>);

class MyContainer{
public:
    void begin(){};
    void end(){};
    size_t size(){return 42;}; 
};

static_assert(SizedContainer<MyContainer>);



int main()
{
}
Pernick answered 10/1, 2018 at 14:26 Comment(3)
First I got hyped and wanted to use the CRTP, but then I remembered MyContainer would be incomplete, and so the concept check would likely fail. So I don't see a better way.Postoperative
@StoryTeller I tried FWD declaration and static assert before class MyContainer, but then it just silently fails... Could be same underlying problem.Pernick
Why is static_assert not an appropriate way to test this? It seems very clear to me what needs to be checked. And the entirety of a class's conceptual interface is not bound by its definition, so there's no reason to expect such checks to be part of the definition.Bobettebobina
B
6

Currently no, the keyword you would be looking for to do that would be requires From cppreference

The keyword requires is used in two ways: 1) To introduce a requires-clause, which specifies constraints on template arguments or on a function declaration.

Since you are not dealing with a function declaration, this is irrelevant. The second case is

To begin a requires-expression, which is a prvalue expression of type bool that describes the constraints on some template arguments. Such expression is true if the corresponding concept is satisfied, and false otherwise:

Which is not relevent here again because you are not trying to validate a constraint on some template arguments

Byran answered 10/1, 2018 at 14:47 Comment(0)
C
0

It's true that there is no native construct for this, and that that without one, the assertion would need to appear after the class is fully specified. However, nonstatic functions themselves are only instantiated after the class is specified, so you could do the somewhat clean:

template <typename T>
concept HasFoo = requires (T t) { t.foo (); };

struct bar {
    void _ () { static_assert (HasFoo<bar>); }

    void foo () {}
};

With void foo() {} removed, this correctly crashes.

Clerkly answered 27/8 at 20:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.