This is related to the following question: Does a class template's requires clause have to be repeated outside member definitions?
In other words, given the code for the following templated struct A
, the requires-clause needs to be repeated for the foo()
function definition (per the standard paragraphs quoted in the linked question above)
template <typename T>
requires std::integral<T> //'requires-clause'
struct A
{
void foo();
};
template <typename T>
requires std::integral<T> //This 'requires-clause' is required by the standard to be reiterated
void A<T>::foo()
{
//
}
//Specialisations do not require explicit 'requires-clause'
template <>
void A<int>::foo()
{
//
}
//Specialisation with a type that does not meet the constraint raises a compile-time error
template <>
void A<double>::foo() //Not allowed because std::integral(double) == false
{
//
}
But I don't know why it is necessary to repeat the requires-clause for the specific class members described in [temp.class]\3. I can't think of a situation where this requirement would make a difference. In the example above, if the requires-clause is with the struct definition, any attempt to instantiate anything that isn't an integral type would not compile, so whether A<T>::foo()
also requires that std::integral<T> == true
is irrelevant. AFAIK it also makes no difference during specialisation because any attempt to specialise to a different type from an integral (as in this example) leads to an compilation error.
However, I'm sure that there are legitimate reasons for including this requirement in the standard - can anybody demonstrate a situation where the absence of this requires-clause
on the definition would cause an issue?
It's quite common to separate a template into 2 files, one being a traditional header, and the second being the implementation, as with non-templated functions and their implementation. The only difference is that you need to #include the template implementation file as well as the header when you want to use it.
Templates in c++ is defined as a blueprint or formula for creating a generic class or a function. To simply put, you can create a single function or single class to work with different data types using templates. C++ template is also known as generic functions or classes which is a very powerful feature in C++.
An individual class defines how a group of objects can be constructed, while a class template defines how a group of classes can be generated. Note the distinction between the terms class template and template class: Class template. is a template used to generate template classes.
What are Class Templates in C++? Templates are the mechanism by which C++ implements the generic concept. Simply, they allow you to pass data type as a parameter so that you don't need to write the same code for different data types.
According to the last section of https://en.cppreference.com/w/cpp/language/constraints you can specialize templates not only on parameters but also on their constraints. Like parameter specializations the standard defines also a partial ordering of constraints, such that a template specialization might be more constrained than another.
So, for example, you may have a more constrained specialization of your template A
:
template <typename T>
requires std::unsigned_integral<T>
struct A
{
void foo();
};
With a different implementation of the element function foo
:
template <typename T>
requires std::unsigned_integral<T>
void A<T>::foo()
{
// different implementation of foo() relying on T being unsigned integral
}
So, without the repeated requires clause in the definitions of both versions of A<T>::foo
the compiler would not know to which specialization of A
the defined foo
would belong.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With