Am 06.02.20 um 18:59 schrieb Jeff Trull:
std::variant. The high compile times stem simply from the fact we have to cycle through the Cartesian product of the set of types of each
I absolutely agree on that diagnosis, but I think std::variant can play a role. The key is to postpone dispatch, where possible, to refactor out one or more of the product terms.
At the moment the dispatch mechanism identifies all the concrete types first, /then/ runs the correct instantiated function. If there were more flexibility in this process, dispatching to selected type-dependent code could happen later and cover less code. Consider:
template<class A, class B, class C> void foo(A a, B b, C c) { // lots of A and B code // a single use of C // lots more A and B }
For the sake of a small amount of code involving C the entire function gets rebuilt as many times as there are C types. Now consider an approach that postponed determining C's concrete type:
template<class A, class B> void foo(A a, B b, std::variant<C1, C2, ...> c_var) { // lots of A and B std::visit([](auto const & c){ // use of C }, c_var); // lots more A and B }
If C was something based on scalar_types this would mean a factor of 6 reduction in instantiations!
But that is not the relevant pattern. What we require is the *joint* instantiation of A B and C types, and a dispatch that is specialized for this joint combination, and hence is as fast as possible. What you are describing (independent dispatching for every type) is not very different from dynamic typing, unless the code can be divided into clear disjoint blocks as in your example, which is not the case for most algorithms in graph-tool. Best, Tiago -- Tiago de Paula Peixoto <tiago@skewed.de>