Re: boost::format vs. in-class 'static const int'
On 2012-01-24 02:42, Jonathan Thornburg wrote:
[[...]]
| * if the class is actually a template, the definition needs to be
| replicated for each instantiation of the template
I don't know what you mean with "replicated", and I don't see a problem
here for you. It is the compiler who has to ignore the multiple
instantiations, not you.
I was thinking of the following slightly-more-elaboprate example,
where the in-class const int lives in a template class:
#include<iostream>
#include<complex>
#include "boost/format.hpp"
using std::cout;
using boost::format;
// identity function
template<typename T> inline T I(T x) { return x; }
// class template containing in-class 'static const int'
template<typename fp>
class foo
{
public:
static const int N = 42;
};
// explicit instantiations of class template
template class foo<double>;
template class foo<long double>;
template class foo< std::complex<double> >;
// must provide an explicit definition of N for each instantiation
template<> const int foo<double>::N;
template<> const int foo<long double>::N;
template<> const int foo< std::complex<double> >::N;
The usage of the explicit *specialization* (not a definition!) of N
without an initializer is the cause of your problem. This is so, because
as of 14.7.3 [temp.expl.spec] p15:
"An explicit specialization of a static data member of a template is a
definition if the declaration includes an initializer; otherwise, it is
a declaration."
Why don't you provide a single primary definition within the header:
template<typename fp>
class foo
{
public:
static const int N = 42;
};
template<typename fp>
const int foo<fp>::N;
?
This was the situation I was referring to, expressing it as "It is the
compiler who has to ignore the multiple instantiations, not you."
Providing a template definition of the static member has the effect that
the compiler has to ensure that effectively only a single definition
exists in the program.
<addendum>
Some compilers don't get this right. In this case a workaround is to
move the initializer to the point of the definition (in the header):
template<typename fp>
class foo
{
public:
static const int N;
};
template<typename fp>
const int foo<fp>::N = 42;
</addendum>
HTH & Greetings from Bremen,
Daniel Kr?gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]