Reputation: 6425
Is it possible to recognize all calling of a certain function in everywhere
function1<T1>(); function1<T4>(); ...
then add a line that calling this following line in a certain place?
function2<T1>(); function2<T4>(); ...
For example,
class X{
template <class T> function1(){ }
template <class T> function2(){ }
}
class A{}
class B{}
class C{}
int main(){
X x;
//vvvv this code (hopefully) will be auto generated (by macro?)
x.function2<A>();
x.function2<B>(); //<--- I don't care about order of A or B
//x.function2<C>(); //<--- this line should not be generated
//^^^^ Only X's function1 should be recognized,
// not other class's functions with the same name.
x.function1<B>();
x.function1<A>();
x.function1<B>(); .... // called in various places in many .cpp
//If it is called in another .cpp, but not here, it should still be recognized
}
My old code call :-
function2<T>() inside function1<T>()
It costs CPU significantly (I profiled), because function1 have to check whether function2 was called or not every time.
Upvotes: 1
Views: 74
Reputation: 32504
Here is a draft of a near-zero overhead solution that will work only if you are not going to invoke function1()
before main()
:
#include <iostream>
#include <typeinfo>
template <class T>
void function2()
{
std::cout << "function2<" << typeid(T).name() << ">()" << std::endl;
}
bool dummy = true;
template <class T>
struct Func1WasInstantiated
{
struct CallFunc2
{
CallFunc2() { function2<T>(); }
void operator()() const { dummy = false; }
};
static CallFunc2 callFunc2;
};
template <class T>
typename Func1WasInstantiated<T>::CallFunc2 Func1WasInstantiated<T>::callFunc2;
template <class T>
void function1()
{
Func1WasInstantiated<T>::callFunc2();
std::cout << "function1<" << typeid(T).name() << ">()" << std::endl;
}
int main()
{
std::cout << "------- Entered main() ---------" << std::endl;
function1<int>();
function1<double>();
function1<int>();
return 0;
}
Output (check it on IDEONE):
function2<i>()
function2<d>()
------- Entered main() ---------
function1<i>()
function1<d>()
function1<i>()
The global variable dummy
is the acceptor of the side effect, that ensures that Func1WasInstantiated<T>::callFunc2
is linked into the program and makes the code work as intended. Without the side effect contained in callFunc2()
I can imagine an aggressively optimizing compiler eliminating that line from function1()
(that is normal) and letting the linker leave out the callFunc2
objects as they become unreferenced (I cannot judge whether this would be against the C++ standard or not).
Upvotes: 1