3

In the example below, I assume there will be two different instantiations of the class template function get_count(), which is redundant since they are not depending on the template parameter. Is this true (or optimized away?), and is there a way to make all instantiations of a template use a common function (maybe some template argument wildcard, like <*>?) when it comes to some member functions?

template<class T>
class A {
    private:
        T obj;
        int count;
    public:
        int get_count(); 
};

template<class T>
int A<T>::get_count() { // This function doesn't really need to
                        // depend on the template parameter.
    return this->count;
}

int main() {
    A<int> a;  //<--First template instantiation
    A<bool> b; //<--Second template instantiation
    int i = a.get_count(); //<--Could theoretically use the same code
    int j = b.get_count(); //<--
    return 0;
}

Also, what if the member variables are re-arranged?

seh
  • 14,999
  • 2
  • 48
  • 58
fast-reflexes
  • 4,891
  • 4
  • 31
  • 44

2 Answers2

4

You are quite mistaken in your assumption that all instantiations can use the same code for A<..>::get_count().

Look at the class members:

    T obj;
    int count;

Thus, the tamplate-argument T determines the offset of count, which is the member get_count() returns.

Anyway, should two instantiations happen to produce the same instructions, nothing prohibits the compiler from mergeing them.
As a QoI-issue, it should if optimizations are enabled.

There is a way to make multiple classes use the same code for a function without relying on compiler-optimization:
Derive from a common base providing that function.

struct A_base {
    int get_count();
protected:
    int count;
}
template<class T>
class A : A_base {
    T obj;
};

int A_base::get_count() {
    return this->count;
}

(Still, in the end the as-if-rule reigns supreme: The compiler may duplicate code to expose optimization possibilities otherwise not useable.)

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
0

Yes, there is a way and it is an implementation technique used:

Make a base class that does not depend on the template parameter and put the template-independent code there. This will make the instantiation only once. For the template parameters dependent code, do it in the template class itself:

class base {
   int count;
public:
    std::size_t get_count()...
};

template <class T>
class derived : public base {};

Similar techniques are used to reduce code bloat in implementations.

Germán Diago
  • 7,473
  • 1
  • 36
  • 59