Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Define a concept in C++ for specific members

I have several structs in the form

struct MyStruct1 {
  std::string myName;
  // ...
}

but not all of them have a member of type std::string and variable named myName.

I'm writing a function template, but I want to restrict access to it, so that only structs that possess this field myName can be passed to the function.

So far, I just tried:

template <typename T>
concept allowedInputType = std::same_as<T, MyStruct1> || std::same_as<T, MyStruct2>; // and so forth

but is there a more elegant way?

like image 467
RocketSearcher Avatar asked Oct 31 '25 11:10

RocketSearcher


1 Answers

If you want to make sure the type has a myName member which is a std::string (or similar), you can define a concept like this:

#include <concepts>
#include <string>

template<typename T>
concept has_myName_string_member = requires {
    { T::myName } -> std::convertible_to<std::string>;
};

Then use it as following:

template <has_myName_string_member T>
void foo([[maybe_unused]] T const& t) {
}

struct S1 {
    std::string myName;
};

struct S2 {
    int myName;
};

struct S3 {
    int a;
};

int main() {
    foo(S1{});
    //foo(S2{});  // MSVC error: error C2672: 'foo': no matching overloaded function found
    //foo(S3{});  // MSVC error: error C2672: 'foo': no matching overloaded function found
}

Live demo 1

Note:
If you want to specify that myName member must be exactly a std::string (and not anything convertible to one), you can use std::same_as<std::string&> instead of std::convertible_to<std::string> in the requires expression of the concept.


If on the other hand you wish to require only the existance of a member by name (but it can be of any type), you can use this concept:

template<typename T>
concept has_myName_member = requires {
    T::myName;
};

And now the above S2 will be accepted (but not S3).

Live demo 2

like image 189
wohlstad Avatar answered Nov 02 '25 00:11

wohlstad



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!