<p>The meaning of <strong>function overloading</strong> is that two or more functions can have the same name but different parameters. In C++20, <a href="https://en.cppreference.com/w/cpp/language/constraints" rel="nofollow noreferrer"><code>concept</code></a> has been introduced. I found that concepts cannot be &quot;overloaded&quot; as in the following code snippet:</p>
<pre><code>template&lt;typename T&gt;
concept is_summable = requires(T x) { x + x; };             //  one parameter version

//  error: redefinition of concept 'is_summable' with different template parameters or requirements
template&lt;typename T&gt;
concept is_summable = requires(T x, T y) { x + y; };        //  two parameter version

template&lt;is_summable T&gt;                                     //  the usage of one parameter version
void foo(T input)
{

}

template&lt;class T1, class T2&gt;
requires(is_summable&lt;T1, T2&gt;)                               //  the usage of two parameter version
void foo(T1 input1, T2 input2)
{

}
</code></pre>
<p>I am wondering the reason of avoiding two or more concepts which have the same name but different number of parameters in C++.</p>

<functions><c++><overloading>
Concept Overloading in C++
<p>Overloading based on type or number of arguments is never a default behaviour, it's a feature that requires extra complexity to implement.</p>
<p>Without overloading, a compiler (or interpreter) can roughly:</p>
<ol>
<li>Identify the context of a name (usually as part of the parser rules)</li>
<li>Look up the name in a table appropriate for that context (e.g. a list of in-scope functions, or in this case concepts)</li>
<li>Use the result of that lookup (e.g. compile a call to that function, or an assertion against the appropriate concept)</li>
</ol>
<p>With overloading, it's no longer a simple name lookup, you need to examine the number of parameters, and do something extra, such as:</p>
<ul>
<li>Have a two-part lookup table, by name and then number of arguments</li>
<li>Perform a &quot;name mangling&quot; step, e.g. internally the name of <code>is_summable</code> is <code>is_summable___1</code> for 1 argument, <code>is_summable___2</code> for 2 arguments</li>
</ul>
<p>If overloading can be on more than just parameter count, e.g. on the <em>type</em> of the parameters, this complexity increases.</p>
<p>Whether this complexity is worthwhile is subjective:</p>
<ul>
<li>On the one hand, it allows the flexibility to have variations such as optional parameters without coming up with extra names</li>
<li>On the other hand, it adds complexity for the <em>user</em> because seeing the name <code>is_summable</code> might not be enough to understand what is being referred to, since the overloaded variants could be arbitrarily different</li>
</ul>
<p>It's also worth noting that adding overloading later is probably a safe change, but removing it would not be. Similarly, once overloading is included, it's harder to change the <em>details</em> of that overloading. Any code that produces a compile-time error in language version X is generally considered safe to give meaning to in version X+1; but changing that meaning, or making it error, is generally a breaking change, which designers strive to avoid.</p>
<p>So the committee presumably decided the complexity was not worthwhile in this case; but they could change their minds and make it possible later, since that wouldn't break any currently compliant code.</p>

CC BY-SA 4.0
2023-12-20T12:01:14.107Z
2023-12-20T12:01:14.107Z
IMSoP
# Concept Overloading in C++
Posted by: username_0 on 2023-12-20
The meaning of function overloading is that two or more functions can have the same name but different parameters. In C++20, concept has been introduced. I found that concepts cannot be "overloaded" as in the following code snippet:
template
concept is_summable = requires(T x) { x + x; };             //  one parameter version

//  error: redefinition of concept 'is_summable' with different template parameters or requirements
template
concept is_summable = requires(T x, T y) { x + y; };        //  two parameter version

template                                     //  the usage of one parameter version
void foo(T input)
{

}

template
requires(is_summable)                               //  the usage of two parameter version
void foo(T1 input1, T2 input2)
{

}

I am wondering the reason of avoiding two or more concepts which have the same name but different number of parameters in C++.
**Tags:** functions c++ overloading
---
## 1 answers
### Answer by username_1 on 2023-12-20. Score: 3 | Accepted answer
Overloading based on type or number of arguments is never a default behaviour, it's a feature that requires extra complexity to implement.

Without overloading, a compiler (or interpreter) can roughly:

1. Identify the context of a name (usually as part of the parser rules)
2. Look up the name in a table appropriate for that context (e.g. a list of in-scope functions, or in this case concepts)
3. Use the result of that lookup (e.g. compile a call to that function, or an assertion against the appropriate concept)

With overloading, it's no longer a simple name lookup, you need to examine the number of parameters, and do something extra, such as:

* Have a two-part lookup table, by name and then number of arguments
* Perform a "name mangling" step, e.g. internally the name of `is_summable` is `is_summable___1` for 1 argument, `is_summable___2` for 2 arguments

If overloading can be on more than just parameter count, e.g. on the *type* of the parameters, this complexity increases.

Whether this complexity is worthwhile is subjective:

* On the one hand, it allows the flexibility to have variations such as optional parameters without coming up with extra names
* On the other hand, it adds complexity for the *user* because seeing the name `is_summable` might not be enough to understand what is being referred to, since the overloaded variants could be arbitrarily different

It's also worth noting that adding overloading later is probably a safe change, but removing it would not be. Similarly, once overloading is included, it's harder to change the *details* of that overloading. Any code that produces a compile-time error in language version X is generally considered safe to give meaning to in version X+1; but changing that meaning, or making it error, is generally a breaking change, which designers strive to avoid.

So the committee presumably decided the complexity was not worthwhile in this case; but they could change their minds and make it possible later, since that wouldn't break any currently compliant code.
---
