Joshua Bloch advises against this in his book titled Effective Java:
That a class uses some constants internally is an implementation detail. Implementing a constant interface causes this implementation detail to leak into the classes' exported API. It is of no consequence to the users of a class that the class implements a constant interface. In fact, it may even confuse them. Worse, it represents a commitment: if in a future release the class is modified so that it no longer needs to use the constants, it still must implement the interface to ensure binary compatibility.
You can get the same effect with a normal class that defines the constants, and then use import static com.example.Constants.*;
If your templates parameters can only assume a finite (and small) set of values, you could move their definition in a source file, and use explicit instantiation.
For instance, in aaa.h
you only declare the template functions f
and g
:
template <int n>
int f();
template <class T>
void g(int a);
Assume n
template parameter can only be 1, 3, 6, and T
template parameter can only be int
, long
and void *
.
Then you define them in aaa.cpp
like this:
template <int n>
int f()
{
...
}
template <class T>
void g(int a)
{
...
}
template int f<1>();
template int f<3>();
template int f<6>();
template void g<int>(int a);
template void g<long>(int a);
template void g<void *>(int a);
In this way the compiler instantiates the template for the given parameters when compiling aaa.cpp
. When compiling client code, it assumes that the definitions exist somewhere, and the linker will take care of that.
#include "aaa.h"
int main()
{
f<1>();
f<3>();
f<6>();
g<int>(5);
g<long>(5);
g<void *>(5);
}
You can explicitly instantiate template classes too. The drawback is that you can not use f
or g
with other template parameters.
#include "aaa.h"
int main()
{
f<5>();
}
results in
undefined reference to `int f<5>()'
I used this technique in a project where few complex classes depended on a small (< 10) set of integer template parameters, and it significantly reduced compilation time (since the compiler did not have to parse the complex template definitions when compiling the client code). Of course you may get lesser improvements, depending on the actual code.
Best Answer
Yes, and it's unnecessary too. You can declare constants in headers and define them in source files just like functions:
Especially in the case of the string, this has the advantage of not constructing a new one every time you access it.
It also has the disadvantage of being affected by C++'s unspecified global initialization order, so be careful if you use the constants from the initialization of other global variables/constants.