Search code examples
c++visual-studioc++20concept

C++20 Concept test not working in MSVS 16.5


I'm new to C++20 concept, but from examples I've seen, this code should work...

#include <iostream>
#include <string>
#include <concepts>
#include <memory>

using namespace std;

struct hasToString
{
    string toString()
    {
        return __FUNCTION__;
    }
};

struct noToString
{
};

template<typename T>
concept has_toString = requires(const T & t)
{
    t.toString();
};

template<typename T>
string optionalToString(const T &obj)
{
    if constexpr (has_toString<T>)
        return obj.toString();
    else
        return "toString not defined";
}

int main()
{
    hasToString has;
    unique_ptr<noToString> hasnt = make_unique<noToString>();

    cout << optionalToString(has) << '\n';
    cout << optionalToString(hasnt) << '\n';
}

Expected output:

hasToString::toString

toString not defined

but instead I get:

toString not defined

toString not defined

What am I doing wrong in such a simple example? I have std:c++latest selected as the C++ Language Standard.


Solution

  • concept has_toString = requires(const T & t)
    {
        t.toString();
    };
    

    Since t is a const object, its toString() method must be a const method. This is not directly related to concepts but with the way C++ class methods have worked even before C++11.

    struct hasToString
    {
        string toString()
        {
    

    And, of course, this toString() is not a const class method. Define it as string toString() const, instead.