0

I am learning about C++20 concepts and I came across the following example that I don't know if it is well-formed(according to the standard) or not. The program is accepted by all compilers: Demo.

Basically, I want to know if this is the correct usage of concepts.

//define Element so that you can use it in vector require clause
template<typename T> bool constexpr Element(){
    if constexpr(std::is_same_v<T, int>)
    {
        return true;
    }
    else 
    {
        return false;
    }
};

template<typename T>        // for all types T
    requires (Element<T>())   // such that T is an Element
class vector {
        //...
};
int main()
{
    vector<int> v;
    
}

My question is that is this well-formed or is it ill-formed NDR. If there is anything wrong then how can we correct it here.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
Kal
  • 475
  • 1
  • 16
  • 2
    Can you explain why, ***exactly***, you suspect this is ill-formed, and what might be wrong with this, and why, exactly, you think that? Or, is this a coding puzzle that you read somewhere, you don't know the answer to, and that's the reason for your question? – Sam Varshavchik Jul 30 '22 at 16:21
  • Why can't you just use `std::same_as`? Also, this code does not contain a "C++20 concept", as evidenced by the lack of the use of the `concept` keyword. – Nicol Bolas Jul 30 '22 at 16:22
  • @SamVarshavchik I want to know if this is the correct usage of C++20 feature `require` clause. Note I am learning C++ and so trying to understand by writing and reading examples. – Kal Jul 30 '22 at 17:03
  • 2
    Bad news: it is not really possible to learn C++ "by writing and reading examples", but only from a [good C++ textbook](https://stackoverflow.com/questions/388242/) that guides you, step by step, through learning and understanding each C++ feature in a logical order that makes sense. Neither Google, nor Stackoverflow, works very well as a textbook replacement. Why do you think this may not be the correct way to use `requires`? – Sam Varshavchik Jul 30 '22 at 17:05
  • 2
    @Kal: Wouldn't it make more sense to read articles/books about the feature rather than typing stuff until your compilers say it's OK and then asking other people if it actually works? – Nicol Bolas Jul 30 '22 at 17:05
  • @SamVarshavchik I am already using the books listed [here](https://stackoverflow.com/questions/388242/). In fact, in my previous posts i often state at the top of my question that i am using those books. In particular i am using C++Primer and C++ Templates: Complete guide. Why people on SO are so judgemental and ready to give advice. I even added an MRE in my question. The question is straightforward and specific. Just saying yes it is well-formed or ill-formed would work and be better. – Kal Jul 30 '22 at 17:13
  • 1
    Well, if this is a practice program from one of those books, then I would think that the book will provide an answer to this. – Sam Varshavchik Jul 30 '22 at 17:14
  • 1
    I can't answer... I am not a language-lawyer ... A hint for you: The language-lawyer tag is typically used if there seems to be some mystery in C++ standards or the standard seems to be unclear for the reader and different compilers produce different results. You as a beginner, not knowing what a concept is, as your examples did not show one, should not tag the questions with language-lawyer :-) – Klaus Jul 30 '22 at 17:20
  • @Kal: "*The question is straightforward and specific.*" But it's so specific that the *only* person who can learn something from the answer... is you. Because your question just asks "is this code OK", the only useful answer is "yes" or "no." But that doesn't explain *why* it is OK or what "OK" even *means* with regard to C++ concepts. If you had a reason for suspecting that it wasn't OK, then other people who had the same misunderstanding about the feature could learn something. But because your question is so focused, it is useless to anybody else. – Nicol Bolas Jul 30 '22 at 17:32
  • @Kal: "*C++Primer and C++ Templates: Complete guide.*" From what I can tell, neither of those books have a recent enough edition to deal with concepts. So I don't know how you would expect to learn anything about concepts from them. – Nicol Bolas Jul 30 '22 at 17:48

2 Answers2

3

There is no "C++ concept" in this code, as evidenced by the lack of the use of the concept keyword. You are using a template definition constrained by a requires clause, but that requires clause doesn't use an actual concept.

As for the validity of the code, it is legal C++. Though it's also really bad C++. Your use of if constexpr over-complicates what could just be return std::is_same_v<T, int>;. Which means that your Element function could be an Element concept rather than a function call: template<typename T> concept Element = std::is_same_v<T, int>;. And since C++20 has the std::same_as concept, you don't even need that. You should always use a standard library concept if one will fit.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
0

Yes, but no! It is well-formed because you are using type traits, which are compile-time boolean values, which are interchangeable with actual concepts and can be part of concept definitions.

At the same time, real concepts support a richer definition and usage syntax than booleans. For example, they can appear in template and function argument lists. Something like the following, although still a bit contrived, would make more sense to me:

#include <concepts>

template<std::integral T>
T constexpr foo_it(T value)
{
    if constexpr(std::same_as<T, int>) {
        // Do something specific for int values
    } else {
        // Generic function body for other integers
    }
    return value;
}

template<std::integral T> 
class vector {
        //...
};

int main()
{
    vector<int> v; // OK
    vector<double> w; // error: double is not integral
}

Your vector class example is odd in the sense that, if you were to design a vector only for integers, it would not need to be a template.

Apart from the usual learning materials, I've found it quite helpful to listen to Bjarne Stroustrup himself on this topic. Here is a short excerpt where he explains it to an interviewer.

sigma
  • 2,758
  • 1
  • 14
  • 18