C++: force complete template compilation (MSVC/G++) - c++

Hello and good day to you.
Following code fragment compiles on cl.exe (15.00.30729.01) and mingw-g++ (4.4.0):
template<typename T> class Test{
public:
T t;
void error(){
int doesNotExist = 6;
return doesNotExist;//<---- void function returning result
}
};
int main(int argc, char** argv){
Test<int> test;
return 0;
}
Also, on cl.exe you can even get away with something like this:
template<typename T> class Test{
public:
T t;
void error(){
doesNotExist = 6;//<---- undeclared variable
return doesNotExist;//<---- void function returning result
}
};
Now, this obviously happens because compiler does not create contents for methods of a template class until somebody calls them. However, this may pose problems when you're designing large template class (because you're very likely to forget to add test call to new method somewhere).
The question:
Is there a compiler switch for g++ or cl.exe that would force compiler to process entire template (so this code fragment will trigger compilation error)?

If you want to test the template with a couple of types, you can trigger manual instantiations of the types, as in:
// at namespace level
template class Test<int>;
Explicit instantiations of class templates automatically trigger the instantiation of all members, which seems to be what you want.
The actual problem is that the language is designed to explicitly allow the behavior that you want to avoid. When a class template is implicitly instantiated, the compiler will instantiate only those methods that are used. The main use case of the feature is that some methods might impose stricter requirements on the instantiating type than others, if all methods were instantiated always then the class template could only be used with those types that fulfill the stricter requirements.
By allowing the compiler to only instantiate those methods that are used, the class template can be used with types that don't meet all of the requirements of all of the methods, as long as they meet the requirements of the methods that are actually used.
A common example is operator[] in std::map<> that requires the value_type to be default-constructible (operator[] will create a new object default initialized if the key is not present in the container and return a reference to it). The behavior in the language allows you to use std::map on types that are not default-constructible as long as you don't use operator[] (or any other member function that imposes that requirement).

Related

Template class with no use of template argument

I have stumbled many times on classes defined like
class PureVirtualClass
{
virtual int foo() = 0;
virtual bool bar() = 0;
}
template <class T> class ImplClass : public virtual PureVirtualClass
{
virtual ~ImplClass(){};
int foo() { return 42;}
bool bar() { return true;}
//several other method having nothing to do with T
}
This "design" appears so often I want to think the original developer knew what he was doing by defining ImplClass as template class but without any reference to the template argument T anywhere. My own c++ template knowledge is kinda limited.
Is there a benefit to this or is it just a confused programmer?
There can be a benefit for classes being templated but not depending on the argument. Most often you see such things to define (empty) tag-structures for template metaprogramming:
template <class X>
struct some_tag {};
The benefit of classes like yours in general is that while you have the same functionality in each class, they are different classes and you can't copy one into the other, i.e. an object of type ImplClass<int> is not compatible with another object of type ImplCalss<float>.
There are many useful cases of the idea mentioned by Arne. For instance, looking at Very basic tuple implementation, this is how a single tuple element is defined:
template <size_t N, typename T>
class TupleElem
{
T elem;
public:
T& get() { return elem; }
const T& get() const { return elem; }
};
It is templated on N, without depending on it. Why? Because the tuple implementation
template <size_t... N, typename... T>
class TupleImpl <sizes <N...>, T...> : TupleElem <N, T>...
{
//..
};
derives multiple such elements, each with a unique N, serving as an identifier. Without it, TupleImpl would be deriving the same class twice, had two element types been identical within parameter pack T.... Neither random access to elements would work in this case (via an explicit call of function get() of the appropriate TupleElem base class, which would be ambiguous), nor empty base optimization (via specializing TupleElem for empty types T to not have a data member of type T).
This is a real use case, and exactly how std::tuple is implemented by clang. Of course, a class like TupleElem would be a hidden implementation detail, and not part of the interface. For instance, gcc follows an entirely different recursive class design.
In general, you will need to study the context where classes are used to understand the intent of the designer.
maybe that developer simply is too lazy to split the classes into .h and .cpp files?
Without using templates, linker errors would occur if the classes are used in multiple compilations units. When using templates, the linker usually discards duplicate instantiations of a template at link time (or handles the problem in a different way).
While this may be an answer to "why did the developer do this", I would not recommend this if the question was "when should I introduce template arguments which are never used" (see the other answers for this). Even though it is annoying to split code into .h and .cpp (especially when used to languages like Java or C#), it's the usual C++ way. And it is definitely easier to read/understand than using templates only for this purpose. Also, it makes the use of the classes less readable.

Call function of template class created at runtime

I have a tricky question about C++(11) template classes and their instantiation with types determined at runtime:
Following scenario:
The user defines the type of a template class using a config file (ROS parameters). This determines only the type of the template class, not the further logic:
Class definition:
template<typename T>
class MyClass {
//[...]
}
Exemplary code:
/* [Read parameter and write result to bool use_int] */
std::unique_ptr<MyClass> myclassptr {nullptr};
if(use_int) {
myclassptr.reset(MyClass<int>);
} else {
myclassptr.reset(MyClass<double>);
}
myclassptr->foobar();
/* [more code making use of myclassptr] */
So this code is (of course) not compiling, because the unique_ptr template must be specified also with the template type. However, then the problem arises that the template type must be the same for all objects assigned using reset.
One ugly solution would be to copy the code myclassptr->foobar(); and the following into each branch of if/else, which I really don't like.
I would like to see a solution similar to this:
/* [Read parameter and write result to bool use_int] */
MyClass<use_int ? int : double> myclass;
myclass.foobar();
What I have read so far is that something like this is also not possible.
Does anybody have a nice solution for this?
The simplest way to do this is:
class IClass{
virtual ~IClass {}
virtual void foobar()=0;
};
template<typename T>
class MyClass:public IClass {
public:
void foobar() override {
// code here
}
};
std::unique_ptr<IClass> myclassptr {};
if(use_int) {
myclassptr.reset(new MyClass<int>());
} else {
myclassptr.reset(new MyClass<double>());
}
myclassptr->foobar();
boost::variant would be another solution, but is usually used for unrelated types. Type erasure could be done, but again that is usually done when you have unrelated types you want to impose a uniform interface on.
In other languages generics look sort of like templates, but are actually an abstract interface with auto-generated typecasting and some typechecking added. C++ templates are function or class compile time factories. Two outputs of such factories are unrelated at runtime by default, and you can add such relations if you want.
Depending on what you want, you can make MyClass a variant type that holds either an int or a double, or you could use type erasure to hide the implementation behind an interface. The Boost.Variant library can help to implement the former.

Is there real static polymorphism in C++?

Here is a simple code in C++:
#include <iostream>
#include <typeinfo>
template<typename T>
void function()
{
std::cout << typeid(T).name() << std::endl;
}
int main()
{
function<int>();
function<double>();
return 0;
}
I have read that templates in C++ is a compile-time feature, which is not like generics in C#/Java.
So as I understood, the C++ compiler will divide a single defined function into various number (depends on calls count with different type) of functions.
Am I right or not? I'm not an expert in C++ compilers, so I'm asking a piece of advice from you.
If my suggestion about compiler output is correct, I want to know if I can describe the code above as static polymorphism?
Because it seems to be not overriding, but just calling a copy from executable or... it doesn't matter what does application have in output binary image, but only the important part is in C++ code level and I musn't look at how does compiler produce an output.
Is there real static polymorhism in C++?
Absolutely - there are three mechanisms for static polymorphism: templates, macros and function overloading.
So as I understood, the C++ compiler will divide a single defined function into various number (depends on calls count with different type) of functions. Am I right or not?
That's the general idea. The number of functions that get instantiated depends on the number of permutations of template parameters, which may be explicitly specified as in function<int> and function<double> or - for templates that use the template parameters to match function arguments - automatically derived from the function arguments, for example:
template <typename T, size_t N>
void f(T (&array)[N])
{ }
double d[2];
f(d); // instantiates/uses f<double, 2>()
You should end up with a single copy of each instantiated template in the executable binary image.
I want to know if I can describe the code above as static polymorphism?
Not really.
template<> function is instantiated for two types
crucially, polymorphism is not used to choose which of the two instantiations of function to dispatch to at the call sites
trivially, during such instantiations typeid(T) is evaluated for int and double and effectively behaves polymorphically from a programmer perspective (it's a compiler keyword though - implementation unknown)
trivially, a mix of static and nominally dynamic (but here likely optimisable to static) polymorphism supports your use of std::cout
Background - polymorphism and code generation
The requirement I consider crucial for polymorphism is:
when code is compiled (be it "normal" code or per template instantiation or macro substitution), the compiler automatically chooses (creates if necessary) - and either inlines or calls - distinct type-appropriate behaviour (machine code)
i.e. code selection/creation is done by the compiler based only on the type(s) of variable(s) involved, rather than being explicitly hard-coded by the programmer's choice between distinct function names / instantiations each only capable of handling one type or permutation of types
for example, std::cout << x; polymorphically invokes different code as the type of x is varied but still outputs x's value, whereas the non-polymorphic printf("%d", x) handles ints but needs to be manually modified to printf("%c", x); if x becomes a char.
But, what we're trying to achieve with polymorphism is a bit more general:
reuse of algorithmic code for multiple types of data without embedding explicit type-detection and branching code
that is, without the program source code containing if (type == X) f1(x) else f2(x);-style code
reduced maintenance burden as after explicitly changing a variable's type fewer consequent changes need to be manually made throughout the source code
These bigger-picture aspects are supported in C++ as follows:
instantiation of the same source code to generate distinct behaviours (machine code) for some other type or permutation of types (this is an aspect of parametric polymorphism),
actually known as "instantiation" for templates and "substitution" for preprocessor macros, but I'll use "instantiation" hereafter for convenience; conceptually, re-compilation or re-interpretation...
implicit dispatch (static or dynamic) to distinct behaviour (machine code) appropriate to the distinct type(s) of data being processed.
...and in some minor ways per my answer at Polymorphism in c++
Different types of polymorphism involve either or both of these:
dispatch (2) can happen during instantiation (1) for templates and preprocessor macros,
instantiation (1) normally happens during dispatch (2) for templates (with no matching full specialisation) and function-like macros (kind of cyclic, though macros don't expand recursively)
dispatch (2) can be happen without instantiation (1) when the compiler selects a pre-existing function overload or template specialisation, or when the compiler triggers virtual/dynamic dispatch.
What does your code actually use?
function<int> and function<double> reuse the function template code to create distinct code for each of those types, so you are getting instantiation (1) as above. But, you are hard-coding which instantiation to call rather than having the compiler implicitly select an instantiation based on the type of some parameter, i.e. so you don't directly utilise implicit dispatch ala (2) when calling function. Indeed, function lacks a parameter that the compiler could use for implicit selection of a template instantiation.
Instantiation (1) alone is not enough to consider your code to have used polymorphism. Still, you've achieved convenient code re-use.
So what would be unambiguously polymorphic?
To illustrate how templates can support dispatch (2) as well as instantiation (1) and unarguably provide "polymorphism", consider:
template<typename T>
void function(T t)
{
std::cout << typeid(T).name() << std::endl;
}
function(4); // note: int argument, use function<int>(...)
function(12.3); // note: double argument, use function<double>(...)
The above code also utilises the implicit dispatch to type-appropriate code - aspect "2." above - of polymorphism.
Non type parameters
Interestingly, C++ provides the ability to instantiate templates with integral parameters such as boolean, int and pointer constants, and use them for all manner of things without varying your data types, and therefore without any polymorphism involved. Macros are even more flexible.
Note that using a template in a C.R.T.P. style is NOT a requirement for static polymorphism - it's an example application thereof. During instantiation, the compiler exhibits static polymorphism when matching operations to implementations in the parameter-specified type.
Discussion on terminology
Getting a definitive definition of polymorphism is difficult. wikipedia quotes Bjarne Stroustrup's online Glossary "providing a single interface to entities of different types": this implies struct X { void f(); }; struct Y { void f(); }; already manifests polymorphism, but IMHO we only get polymorphism when we use the correspondence of interface from client code, e.g. template <typename T> void poly(T& t) { t.f(); } requires static polymorphic dispatch to t.f() for each instantiation.
Wikipedia lists three types of polymorphism:
If a function denotes different and potentially heterogeneous implementations depending on a limited range of individually specified
types and combinations, it is called ad hoc polymorphism. Ad hoc
polymorphism is supported in many languages using function
overloading.
If the code is written without mention of any specific type and thus can be used transparently with any number of new types, it is
called parametric polymorphism. In the object-oriented programming
community, this is often known as generics or generic programming. In
the functional programming community, this is often simply called
polymorphism.
Subtyping (or inclusion polymorphism) is a concept wherein a name may denote instances of many different classes as long as they are
related by some common superclass. In object-oriented programming,
this is often referred to simply as polymorphism.
The first one refers to function overloading. The third type refers to late binding or runtime polymorphism, the kind you would see for example in inheritance. The second one is what we're interested in.
Templates are a compile-time construct and type deduction is a process when the compiler automatically figures out the template arguments. This is where static polymorphism comes in.
For example:
template <typename T, typename U>
auto func(const T& t, const U& u) -> decltype(t + u)
{
return (t + u);
}
This will work for any two types with compatible plus operators. There's no need to specify the template argument if the compiler can figure it out. It would be ad hoc polymorphism if you wrote function overloads that performed different behavior, for example string concatenation vs integer addition.
However, in your example, you have instantiations for your functions that are distinct, function<int> and function<double>. Here's a quote:
To be polymorphic, [a()] must be able to operate with values of at
least two distinct types (e.g. int and double), finding and executing
type-appropriate code.
In that case, the instantiations are specific for the type in which they were instantiated, so there is no polymorphism involved.
There is no static polymorphism in your example because there is no polymorphism. This is because function<int>() does not look the same as function<double>().
Examples of static polymorphism would include simple function overloading, function templates that can work with type deduction, type traits, and the curiously recurring template pattern (CRTP). So this variation on your example would qualify as static polymorphism:
#include <iostream>
#include <typeinfo>
template<typename T>
void function(T)
{
std::cout << typeid(T).name() << std::endl;
}
int main()
{
function(0); // T is int
function(0.0); // T is double
return 0;
}
Here is another example:
template<typename T>
void function(T t)
{
t.foo();
}
struct Foo()
{
void foo() const {}
};
struct Bar()
{
void foo() const {}
};
int main()
{
Foo f;
Bar b;
function(f); // T is Foo
function(b); // T is Bar
}
For c++ the term 'static polymorphism' is normally used for e.g. the CRTP type design patterns:
template<typename Derived>
class Base
{
void someFunc() {
static_cast<Derived*>(this)->someOtherFunc();
};
};
class ADerived : public Base<ADerived>
{
void someOtherFunc() {
// ...
}
};
It generally means that types and inheritance constraints are deduced and verified at compile/link time. The compiler will emit error messages if operations are missing or invalid on the specified types. In that sense it's not really polymorphism.
While it can be argued that the example in the OP does not exhibit static polymorphism, the use of specialization can make a more compelling case:
template<class T>
class Base
{
public:
int a() { return 7; }
};
template<>
class Base<int>
{
public:
int a() { return 42; }
};
template<>
class Base<double>
{
public:
int a() { return 121; }
};
We see here that for most classes a() will return 7; The specialized (derived) instanciations for int and double can have radically different behaviors, demonstrated in the simple case by the differing return values, the same can be done for templates with for example int parameters, and can exhibit what can be oddly termed as static recursive polymoprphism.
While the term polymorphic is possibly being stretched, the concept is definately there. What is missing is not the ability to redefine functions, but the ability for specialized classes to automatically inherit functions that are not changing behavior.

Can instantiation of a template lead to a binary code duplication, does compiler prevent it?

Suppose, we declare the template:
template <class functor, int index>
class MyClass
{
public:
MyClass(){someFunction(index);}
private:
void someFunction(int index)
{
while(index--)
functor();
}
int commonFunction(void)
{
return M_PI;
}
};
Pay attention that the method commonFunction doesn`t depend on the template parameters.
Client uses this template:
MyClass<func1,100> t1;
MyClass<func2,100> t2;
// ...
MyClass<funci,100> ti;
// where i, for example in 1 .. 1000
Will instantiation of the template lead to the duplication of commonFunction in the binary code?
Can a compiler prevent that duplication?
Does C++ standart defines that duplication can be prevented, so every compiler should provide optimization?
Of course this can be easily solved by implementing common functionality for all templates in a base class and moving differences in the templated class, like this:
class baseMyClass
{
int commonFunction(void)
{
return M_PI;
}
};
template <class functor, int index>
class MyClass : private baseMyClass
{
public:
MyClass(){someFunction(index);}
private:
void someFunction(int index)
{
while(index--)
functor();
}
};
But the purpose of my question is to find out:
Does standart defines that in the cases that look like the one I gave optimization should be performed, so we can simply use template and rely on a compiler?
Does standart defines that in the cases that look like the one I gave optimization should be performed, so we can simply use template and rely on a compiler?
No, the Standard does not require by any means that conforming compilers perform such kind of optimization. Code bloating is known to be one of the drawbacks of templates.
This said, since your function does not do anything else than returning a constant, it will probably be inlined, and even in case it will not be inlined, it is possible that the linker will recognize that several identical instantiations of that function have been generated, and merge them all.
However, this behavior is not mandated by the Standard.
The standard does not mandate optimisation on any case. So the answer to your last question is no for any case you can think of. Now, the standard does not prevent optimisation either in this case, and I guess many compilers will be smart enough to do it in this simple case.

Any way to determine if class implements operator()

I'm trying to find is there's a way to check if a class is a functional because i want to write a template which uses it?
Is there an easy way to do this? Or do I just wrap things in a try/catch? Or perhaps the compiler won't even let me do it?
If you have a function template written like:
template <typename T>
void f(T x)
{
x();
}
you will be unable to instantiate it with any type that is not callable as a function taking no arguments (e.g., a class type that overloads operator() taking no arguments is callable as a function that takes no arguments). You would get a compilation error if you tried to do so.
This is the simplest way to require the type with which a template is instantiated to have certain properties: just rely on the type having those properties when you write the template, and if the type doesn't have one of the required properties, it will be impossible to instantiate the template with that type.
There are quite a few ways a parameter type can be applicable to the call syntax
Type is a pointer or reference to a function type, or
Type is a class-type which has a conversion function to one of the types in 1., or has an applicable operator().
The current C++ cannot check for 2., so you are left without checking, like the other answers explain.
This would fall under doing it and getting a compiling error. When the code is compiled the template function or template classes are are expanded for the types used as if there were duplicate copies of that template code, one for each type.
So you can basically do whatever and as long as all the types used for your templates support it you have no problem. If they don't support it you have a compiling error and you can't run your code without fixing it.
template <typename T>
void DoIt(T a)
{
a.helloworld();//This will compile fine
return a();//This will cause a compiling error if T is B
}
class A
{
public:
void a.helloworld(){}
void operator()(){}
};
class B
{
public:
void a.helloworld(){}
};
int main(int argc, char**argv)
{
A a;
B b;
DoIt(a);
DoIt(b);//Compiling error
return 0;
}
If you actually need a test to see if type T implements an operator() of some given signature then you could use the same SFINAE trick used to identify the existence of any other class member that is discussed here: C++ "if then else" template substitution