Luc Bourhis | 25 Jun 2012 01:22
Picon
Gravatar

[boost::format] operator % could use call_traits<..>::parameter_type

Hi,

consider a library featuring code like

template <..., unsigned Rank, ...> struct Foo { ... static unsigned const rank = Rank; .... };

as well as

boost::format(...) % Foo::rank

Such code will link if and only if a definition for Foo::rank is provided because the interface of operator % is

template <class T>
operator%(const T& x)

This is not possible in the library, as I do not know which values of Rank will be used by client code. Thus the
only possibility is a hat trick like

boost::format(...) % (Foo::rank+0)

If operator % took integral types by value instead, this would alleviate the problem. Hence the suggestion
to use call_traits<T>::parameter_type instead of T const &.

Of course, the same could be said of many functions other than format::operator%

Best wishes,

Luc Bourhis
Krzysztof Czainski | 25 Jun 2012 11:22
Picon

Re: [boost::format] operator % could use call_traits<..>::parameter_type

2012/6/25 Luc Bourhis <luc_j_bourhis <at> mac.com>
Hi,

consider a library featuring code like

template <..., unsigned Rank, ...> struct Foo { ... static unsigned const rank = Rank; .... };

as well as

boost::format(...) % Foo::rank

Such code will link if and only if a definition for Foo::rank is provided because the interface of operator % is

template <class T>
operator%(const T& x)

This is not possible in the library, as I do not know which values of Rank will be used by client code. Thus the only possibility is a hat trick like

boost::format(...) % (Foo::rank+0)

Hi,

For problems like this I use a trick a bit simpler:
boost::format(...) % +Foo::rank

Notice, that if foo looks uses some char type instead of int, like this:
typedef int8_t-or-char MyInt;
template <..., MyInt Rank, ...> struct Foo { ... static MyInt const rank = Rank; .... };
then both our above tricks change the behavior of format by promoting Rank to int, which is treated totally different than char. In my case the "char" behavior was unexpected, and the trick fixed that as well ;-)

My 0.02 cents.
Regards
Kris
_______________________________________________
Boost-users mailing list
Boost-users <at> lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Luc Bourhis | 25 Jun 2012 12:42
Picon
Gravatar

Re: [boost::format] operator % could use call_traits<..>::parameter_type

Hi,

> For problems like this I use a trick a bit simpler:
> boost::format(...) % +Foo::rank

Neat! I had not thought of that. 

However, and I did not explain it in my original post, what I actually did was to define a function with a long
winded name like
alleviate_static_integral_const_member_definition to hide the trick and make it plain obvious there
is a potential problem there. 
Call me paranoid but I am always afraid of cute notations in a large project on the long term.

> Notice, that if foo looks uses some char type instead of int, like this:
> typedef int8_t-or-char MyInt;
> template <..., MyInt Rank, ...> struct Foo { ... static MyInt const rank = Rank; .... };
> then both our above tricks change the behavior of format by promoting Rank to int, which is treated totally
different than char. In my case the "char" behavior was unexpected, and the trick fixed that as well ;-)

Good point. Not a problem in my case but I could change my function to

template<class T> typename boost::enable_if<boost::is_integral<T>, T >::type 
alleviate_static_integral_const_member_definition(T x) { 
	return x; 
}

for safety.

Gmane