Re: question on c++ constants?
On Oct 17, 3:28 pm, James Kanze <james.ka...@gmail.com> wrote:
On Oct 16, 6:58 pm, gpderetta <gpdere...@gmail.com> wrote:
This is not a made up example, I often find the need to name
function object instances in header files, but, if the
anonymous namespace is dropped, you will get multiple
definitions for 'bar'. The only workaround I know (from the
boost mailing list) is:
template <class F> struct instance_of { static T value; };
template<class T> T instance_of<T>::value = {}
namespace { my_functor_type const& bar =
instance_of<my_functor_type>::value; }
template<class T> void foo(T x) {
bar(x);
}
Typical Boost:-). Why do simple when you can do complicated:
namespace Whatever_Private
{
extern my_functor_type bar ;
} ;
That's the best solution of course. But see at the end.
Or if you really need to be headers only:
namespace Whatever_Private
{
inline my_functor_type& bar()
{
static my_functor_type theOneAndOnly ;
return theOneAndOnly ;
}
} ;
Well, as my function objects are stateless 99% of the times, if I have
to use an extra set of (), I might as well just instantiate the
function object on the fly. The idea is to use the same syntax for
function objects and functions (i.e. the user doesn't really need to
know if a certain function is really a function or a function object,
up to a point of course).
Now there won't be any ODR violations in 'foo', if the ODR
rule is interpret as only requiring all symbols to bind to the
same objects in all translation units.
If you want the library to be headers only, then you need to
encapsulate the definition in something which can appear in
multiple compilation units: a template or an inline function.
Generally, you're better off dropping the headers only
requirement, however.
Often, at least in my code, function objects are compile time
polymorphic (i.e. they have a templated operator(); in fact if it is
not polymorphic there is little need to define a function object in
the first place), so you have to define them in the header anyway.
Having a .cc file just to contain their instantiation is just ugly. I
should probably write a tool that generate such .cc files on the fly
and just add it to the build system.
--
gpd