This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
int sumScale(int a, int b, int c) { | |
return c*(a + b); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
template <class T> | |
T sumScale(T a, T b, int c) { | |
return c*(a + b); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
sumScale.cpp: In instantiation of ‘T sumScale(T, T, int) [with T = Point]’: | |
sumScale.cpp:24:26: required from here | |
sumScale.cpp:13:15: error: no match for ‘operator+’ (operand types are ‘Point’ and ‘Point’) | |
return c*(a + b); | |
~~~^~~~ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
sumScale.cpp: In instantiation of ‘T sumScale(T, T, int) [with T = Point]’: | |
sumScale.cpp:28:26: required from here | |
sumScale.cpp:17:11: error: no match for ‘operator*’ (operand types are ‘int’ and ‘Point’) | |
return c*(a + b); | |
~^~~~~~~~ |
Sometime that Point type is defined in an header that makes your entire project to recompile every time you add a missing feature.
Let see how can concepts can save our time and some headache.
Basically that sumScale function has a strong requirement on the type T. It should be a summable type (it has to support the operator+) and it should be scalable (it has to support operator* with an int), we can express these two concepts in the following way:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
template <class T> | |
concept bool SummableScalable() { | |
return requires(T a, T b, int c) { | |
{a + b}->T; | |
{c * a}->T; | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
SummableScalable sumScale(SummableScalable a, SummableScalable b, int c) { | |
return c*(a + b); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
sumScale_concepts.cpp: In function ‘int main()’: | |
sumScale_concepts.cpp:40:26: error: cannot call function ‘auto sumScale(auto:1, auto:1, int) [with auto:1 = Point]’ | |
auto c = sumScale(a,b,3); | |
^ | |
sumScale_concepts.cpp:28:18: note: constraints not satisfied | |
SummableScalable sumScale(SummableScalable a, SummableScalable b, int c) { | |
^~~~~~~~ | |
sumScale_concepts.cpp:21:14: note: within ‘template<class T> concept bool SummableScalable() [with T = Point]’ | |
concept bool SummableScalable() { | |
^~~~~~~~~~~~~~~~ | |
sumScale_concepts.cpp:21:14: note: with ‘Point a’ | |
sumScale_concepts.cpp:21:14: note: with ‘Point b’ | |
sumScale_concepts.cpp:21:14: note: with ‘int c’ | |
sumScale_concepts.cpp:21:14: note: the required expression ‘(a + b)’ would be ill-formed | |
sumScale_concepts.cpp:21:14: note: the required expression ‘(c * a)’ would be ill-formed |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
template <class T> | |
T sumScale(T a, T b, int c) { | |
return c*(a + b); | |
} | |
SummableScalable sumScale(SummableScalable a, SummableScalable b, int c) { | |
return c*(a + b); | |
} |
Let's go back now to our concept:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
template <class T> | |
concept bool SummableScalable() { | |
return requires(T a, T b, int c) { | |
{a + b}->T; | |
{c * a}->T; | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
template <class T> | |
concept bool Summable() { | |
return requires(T a, T b) { | |
{a + b}->T; | |
}; | |
} | |
template <class T> | |
concept bool SummableScalable() { | |
return Summable<T>() && | |
requires(T a, int c) { | |
{c * a}->T; | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
template <class T> | |
concept bool Summable() { | |
return requires(T a, T b) { | |
{a + b}->T; | |
}; | |
} | |
template <class T> | |
concept bool Scalable() { | |
return requires(T a, int c) { | |
{c * a}->T; | |
}; | |
} | |
template <class T> | |
concept bool SummableScalable() { | |
return Summable<T>() && | |
Scalable<T>(); | |
} |
2 comments:
Concepts look like a good idea but I feel the implementation is terrible : 2 new keywords and adding an overload to the semantics of '->' operator.
In C# you can use constraints on type parameters to achieve a similar effect. Although you will loose the benefits of duck typing, I think it is better integrated in the language so more widely understandable.
Here is a short example : https://dotnetfiddle.net/IFYLOY
Mr. Monkey. The proposal didn't make it in C++17 so you are still in time to make a better proposal.
Post a Comment