aboutsummaryrefslogtreecommitdiff
path: root/articles/2014-01-05_disabling_methods_in_implicitly_instantiated_class_template_specia...
diff options
context:
space:
mode:
authorAdrian Kummerlaender2014-08-10 13:09:42 +0200
committerAdrian Kummerlaender2014-08-10 13:09:42 +0200
commitf4043ec1e9f02efc7f653274b9e4e22ef2782a51 (patch)
tree7094d038dd30eef441b6895a2ac99daf5720e7d4 /articles/2014-01-05_disabling_methods_in_implicitly_instantiated_class_template_specializations_in_cpp.md
parent8d7f2c536f3c48d17b1de244fe6713f4d4499fd5 (diff)
downloadblog_content-f4043ec1e9f02efc7f653274b9e4e22ef2782a51.tar
blog_content-f4043ec1e9f02efc7f653274b9e4e22ef2782a51.tar.gz
blog_content-f4043ec1e9f02efc7f653274b9e4e22ef2782a51.tar.bz2
blog_content-f4043ec1e9f02efc7f653274b9e4e22ef2782a51.tar.lz
blog_content-f4043ec1e9f02efc7f653274b9e4e22ef2782a51.tar.xz
blog_content-f4043ec1e9f02efc7f653274b9e4e22ef2782a51.tar.zst
blog_content-f4043ec1e9f02efc7f653274b9e4e22ef2782a51.zip
Switched content formatter to kramdown
* implemented language selection for automatic syntax highlighting ** language selection requires the language to be used to be passed as a class of the code element ** kramdown enables easy definition of this class attribute * kramdown offers more functionality such as table and class attribute support * updated all articles accordingly
Diffstat (limited to 'articles/2014-01-05_disabling_methods_in_implicitly_instantiated_class_template_specializations_in_cpp.md')
-rw-r--r--articles/2014-01-05_disabling_methods_in_implicitly_instantiated_class_template_specializations_in_cpp.md67
1 files changed, 38 insertions, 29 deletions
diff --git a/articles/2014-01-05_disabling_methods_in_implicitly_instantiated_class_template_specializations_in_cpp.md b/articles/2014-01-05_disabling_methods_in_implicitly_instantiated_class_template_specializations_in_cpp.md
index 55da8fd..610254e 100644
--- a/articles/2014-01-05_disabling_methods_in_implicitly_instantiated_class_template_specializations_in_cpp.md
+++ b/articles/2014-01-05_disabling_methods_in_implicitly_instantiated_class_template_specializations_in_cpp.md
@@ -5,16 +5,19 @@ During my current undertaking of developing a [template based library](https://g
The specific scenario I am talking about is disabling the _serialize_ and _deserialize_ template methods in all specializations of the
_[Tuple](https://github.com/KnairdA/BinaryMapping/blob/master/src/tuple/tuple.h)_ class template whose _Endianess_ argument is not of the type _UndefinedEndian_. My first working implementation of this requirement looks as follows:
- template <
- typename CustomOrder,
- typename Helper = Endianess
- >
- inline typename std::enable_if<
- std::is_same<UndefinedEndian, Helper>::value,
- void
- >::type serialize() {
- Serializer<InPlaceSorter<CustomOrder>>::serialize(this->tuple_);
- }
+~~~
+template <
+ typename CustomOrder,
+ typename Helper = Endianess
+>
+inline typename std::enable_if<
+ std::is_same<UndefinedEndian, Helper>::value,
+ void
+>::type serialize() {
+ Serializer<InPlaceSorter<CustomOrder>>::serialize(this->tuple_);
+}
+~~~
+{: .language-cpp}
As we can see I am relying on the standard libraries `std::enable_if` template to enable the method only if the _Helper_ template argument equals the type _UndefinedEndian_. One may wonder why I am supplying the `std::enable_if` template with the argument _Helper_ instead of directly specifying the class template argument _Endianess_. This was needed because of the following paragraph of the ISO C++ standard:
@@ -27,16 +30,19 @@ I defined a additional _Helper_ argument which defaults to the class template's
The code supplied above works as expected but has at least two flaws: There is an additonal template argument whose sole purpose is to work around the C++ standard to make _[SFINAE](https://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error)_ possible and the return type of the method is obfuscated by the use of the `std::enable_if` template.
Luckily it is not the only way of achieving our goal:
- template <
- typename CustomOrder,
- typename = typename std::enable_if<
- std::is_same<UndefinedEndian, Endianess>::value,
- void
- >::type
- >
- inline void serialize() {
- Serializer<InPlaceSorter<CustomOrder>>::serialize(this->tuple_);
- }
+~~~
+template <
+ typename CustomOrder,
+ typename = typename std::enable_if<
+ std::is_same<UndefinedEndian, Endianess>::value,
+ void
+ >::type
+>
+inline void serialize() {
+ Serializer<InPlaceSorter<CustomOrder>>::serialize(this->tuple_);
+}
+~~~
+{: .language-cpp}
In this second example implementation we are moving the `std::enable_if` template from the return type into a unnamed default template argument of the method. This unnamed default
template argument which was not possible prior to the C++11 standard reduces the purpose of the `std::enable_if` template to selectively disabling method specializations. Additionally
@@ -44,15 +50,18 @@ the return type can be straight forwardly declared and the _Helper_ template arg
But during my research concerning this problem I came up with one additional way of achieving our goal which one could argue is even better than the second example:
- template <typename CustomOrder>
- inline void serialize() {
- static_assert(
- std::is_same<Endianess, UndefinedEndian>::value,
- "Endianess must be UndefinedEndian to use serialize<*>()"
- );
-
- Serializer<InPlaceSorter<CustomOrder>>::serialize(this->tuple_);
- }
+~~~
+template <typename CustomOrder>
+inline void serialize() {
+ static_assert(
+ std::is_same<Endianess, UndefinedEndian>::value,
+ "Endianess must be UndefinedEndian to use serialize<*>()"
+ );
+
+ Serializer<InPlaceSorter<CustomOrder>>::serialize(this->tuple_);
+}
+~~~
+{: .language-cpp}
This implementation of the _serialize_ method renounces any additonal template arguments and instead uses a declaration called `static_assert` which makes any specializations where
the statement `std::is_same<Endianess, UndefinedEndian>::value` resolves to false ill-formed. Additionally it also returns a helpful message to the compiler log during such a situation.