Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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)?

like image 570
SigTerm Avatar asked Nov 02 '11 10:11

SigTerm


1 Answers

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).

like image 184
David Rodríguez - dribeas Avatar answered Sep 30 '22 20:09

David Rodríguez - dribeas