How to choose a method at compile time?

I remember reading an article using the new C ++ features to implement choices at compiler time, but I can't figure out how to do this. For example, I have a method that does the following

template<class T> void foo() { if (std::is_abstract<T>::value) do something; else do others. } 
+4
source share
3 answers

If both of your branches are compiled, the above code is actually OK and will make a choice at compile time: there will be one branch that the compiler will consider dead and never use. Optimization of non-compliance by the compiler will use a branch.

Especially when branches cannot compile depending on type, you can use std::enable_if to conditionally create overloads:

 template <typename T> typename std::enable_if<std::is_abstract<T>::value>::type foo() { do something } template <typename T> typename std::enable_if<!std::is_abstract<T>::value>::type foo() { do other } 
+5
source

The compilation decision process is usually performed by selecting the overload.

 void foo_impl(std::true_type) { do something; } void foo_impl(std::false_type) { do others. } template<class T> void foo() { foo_impl(std::is_abstract<T>()); } 
+7
source

The std::is_abstract is an example of a trait, and I like to follow the classic idiom of choice:

 #include<iostream> #include<type_traits> template<bool> struct algorithm_selector { static void implementation() { std::cout<<"I am using the default implementation"<<std::endl; } }; template<> struct algorithm_selector<true> { static void implementation() { std::cout<<"I am using the 'custom' implementation"<<std::endl; } }; template<typename T> void foo() { algorithm_selector<std::is_abstract<T>::value>::implementation(); } struct ABC { virtual void bar() const = 0; }; struct Derived : ABC { }; struct Blah {}; int main() { foo<ABC>(); foo<Derived>(); foo<Blah>(); return 0; } 

Compiled as (gcc 4.8.1) g++ example.cpp -std=c++11 gives the output:

 I am using the 'custom' implementation I am using the 'custom' implementation I am using the default implementation 

What I like about this is that it goes beyond the logic of * enable_if * (at least conceptually): it gives me an idiom that I can use to select arbitrary strategies at compile time. Most likely, this is a matter of preference, but for me this idiom is solid rock. In addition, check out the policy templates described in the book by Andrei Alexandrescu ; they are associated with this flexibility in compiled-time powered design.

+1
source

Source: https://habr.com/ru/post/1502223/


All Articles