Sometimes, in the course of C++ template based programming it might be desirable to have a constructor that is templated, like the following contrived exampled:
#include <iostream> struct TestClass { template<typename T> TestClass(const T &t) { std::cout << "Constructed a TestClass " << t << std::endl; } };
By creating a templated constructor, however, we have created an infinite number of automatic type conversions. That is, the following code does compile:
void TakeATestClass(const TestClass &t) { } int main() { TakeATestClass("Bob"); }
Is the above something that we really expected to compile? Probably not, but even if it is, the chance that we will lose track of it down the road and it will come back to bite us is pretty high.
In fact, this takes principle #40 from C++ Coding Standards, "Avoid providing implicit conversions," and raises it to the Nth degree.
The solution is simple. We can still retain the flexibility of the templated constructor while eliminating the accidental conversions by adding the "explicit" keyword to our constructor.
struct TestClass { template<typename T> explicit TestClass(const T &t) { std::cout << "Constructed a TestClass " << t << std::endl; } };
Our new version should eliminate all unintended constructions of our new class.
Comments
newbie point: you don't
newbie point: you don't provide an example of an intended construction.
not compiling
hello,
it does not compile indeed.
the output:
g++ vs gcc
Consider using g++ to compile a c++ application instead of gcc. The errors you are seeing is the compiler not linking to the standard C++ library.
-Jason
What about a templated template?
So what about this case:
Bar is defined in an included file.
This generates an error for me, and I'm uncertain how to proceed.
Can you provide a more
Can you provide a more complete example? Example of the definition of Bar and example usage of the constructor, and I can check it out.
-Jason