c++c++20c++-conceptsrequires-expression

How do I write a C++ requires expression that looks for specific member functions/static functions with arguments?


How can I write a C++ requires expression that looks for specific member functions or static functions, with specific argument types?

For example:

struct ConcretePrintable {
    static std::string StaticDescription() { return "static description"; }
    std::string Description() { return "description"; }
    std::string Greet(std::string_view name) { return std::format("Hi, {}!", name); }
};

template <typename T>
concept Printable = requires(T t) {
    { T::StaticDescription() } -> std::same_as<std::string>; // Require that T has a static function (that returns a string) named `StaticDescription`

    { t.Description() } -> std::same_as<std::string>; // Require that T have a member function (that returns a string) named `Description`

    // TODO: how to test for the `Greet` method?
    // { t.Greet(declval(std::string_view)) } -> std::same_as<std::string>;
};

https://godbolt.org/z/x5rG6fG87


Solution

  • There are several approaches that work!

    Approach 1: if the types are default-constructable

    template <typename T>
    concept Printable = requires(T t) {
        // ...
    
        // If the type is default-constructable:
        { t.Greet(std::string_view{}) } -> std::same_as<std::string>;
    };
    

    https://godbolt.org/z/s3KKvdMEz

    Approach 2: add the type to the requires statement

    template <typename T>
    concept Printable = requires(T t, const std::string_view& s) {
        // ...
    
        { t.Greet(s) } -> std::same_as<std::string>;
    };
    

    https://godbolt.org/z/51Mf744cE