Non penso che tu possa dipendere da ciò che accade con i compilatori attuali.
Piuttosto che g_aux()
suggerito nei commenti, potresti prendere in considerazione l'utilizzo dell'ereditarietà:
class base {
public:
int g() { return 0; }
};
template <int N>
class Foo : public base {
public:
int f() { return N; }
};
Con questo è ancora possibile che il compilatore possa generare il codice inline per g
se è abbastanza semplice, ma sulla base dei tuoi commenti dubito che sia davvero una preoccupazione. Senza inlining ... beh, g()
è un membro di una classe, quindi possiamo aspettarci che ogni compilatore ne generi esattamente una copia.
Poiché questo non è inteso per consentire la conversione alla classe base, il modo teoricamente corretto per farlo sarebbe probabilmente quello di rendere g()
una funzione membro protetta, utilizzare l'ereditarietà privata e aggiungere using base::g;
alla classe derivata per rendere g()
(e solo g, non la classe base stessa) visibile al mondo esterno:
#include <iostream>
class base {
protected:
int g() { return 0; }
};
template <int N>
class Foo : private base {
public:
using base::g;
int f() { return N; }
};
int main() {
Foo<3> a;
Foo<4> b;
std::cout << a.g() << "\n" << b.g() << "\n"; // <-- no problem
// base *c = &a; // <-- fails
}