Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compiler warning at C++ template base class

I get a compiler warning, that I don't understand in that context. When I compile the "Child.cpp" from the following code. (Don't wonder: I stripped off my class declarations to the bare minimum, so the content will not make much sense, but you will see the problem quicker). I get the warning with Visual Studio 2003 and Visual Studio 2008 on the highest warning level.


The code

AbstractClass.h:

#include <iostream>

template<typename T>
class AbstractClass
{
    public:
        virtual void Cancel(); // { std::cout << "Abstract Cancel" << std::endl; };
        virtual void Process() = 0;
};

// Outside definition. If I comment out this and take the inline
// definition like above (currently commented out), I don't get
// a compiler warning.
template<typename T>
void AbstractClass<T>::Cancel()
{
    std::cout << "Abstract Cancel" << std::endl;
}

Child.h:

#include "AbstractClass.h"

class Child : public AbstractClass<int>
{
    public:
        virtual void Process();
};

Child.cpp:

#include "Child.h"
#include <iostream>

void Child::Process()
{
    std::cout << "Process" << std::endl;
}

The warning

The class "Child" is derived from "AbstractClass". In "AbstractClass" there's the public method "AbstractClass::Cancel()". If I define the method outside of the class body (like in the code you see), I get the compiler warning...

AbstractClass.h(7) : warning C4505: 'AbstractClass::Cancel' : unreferenced local function has been removed with [T=int]

...when I compile "Child.cpp". I do not understand this, because this is a public function, and the compiler can't know if I later reference this method or not. And, in the end, I reference this method, because I call it in main.cpp and despite this compiler warning, this method works if I compile and link all files and execute the program:

//main.cpp
#include <iostream>
#include "Child.h"

int main()
{
    Child child;
    child.Cancel();  // Works, despite the warning
}

If I do define the Cancel() function as inline (you see it as out commented code in AbstractClass.h), then I don't get the compiler warning. Of course my program works, but I want to understand this warning or is this just a compiler mistake?

Furthermore, if do not implement AbsctractClass as a template class (just for a test purpose in this case) I also don't get the compiler warning...?


If I make a non-virtual function, I don't get the compile warning for that non-virtual function, but all answers up to now don't comprise the virtual stuff. Try this:

template<typename T>
class AbstractClass
{
    public:
        virtual void Cancel(); // { std::cout << "Abstract Cancel" << std::endl; };
        virtual void Process() = 0;
        void NonVirtualFunction();
};

//...

template<typename T>
void AbstractClass<T>::NonVirtualFunction()
{
    std::cout << "NonVirtualFunction" << std::endl;
}

The answers up to know helped me, but I don't think that the question is fully answered.

like image 648
eike Avatar asked Jun 16 '10 09:06

eike


People also ask

What is the rule of compiler by templates?

The compiler usually instantiates members of template classes independently of other members, so that the compiler instantiates only members that are used within the program. Methods written solely for use through a debugger will therefore not normally be instantiated.

What is a compile warning?

Apr 05 2013. Compiler warnings are messages produced by a compiler regarding program code fragments to be considered by the developer, as they may contain errors. Unlike compilation errors, warnings don't interrupt the compilation process.

Can template class inherit?

Inheriting from a template classIt is possible to inherit from a template class. All the usual rules for inheritance and polymorphism apply. If we want the new, derived class to be generic it should also be a template class; and pass its template parameter along to the base class.

What is a class template C?

A class template provides a specification for generating classes based on parameters. Class templates are generally used to implement containers. A class template is instantiated by passing a given set of types to it as template arguments.


1 Answers

The warning simply says that the linker cannot see any usage of the function.

If you want to"tell" the linker to avoid the warning you can fool the linker into "think" it is in use.

For example:

void MyLinkerThinkNotUsedFunction
{
}

void* Foo = (void*)MyLinkerThinkNotUsedFunction;

will suffice to avoid any warning C4505 on the function MyLinkerThinkNotUsedFunction.

like image 53
user3409863 Avatar answered Sep 27 '22 19:09

user3409863