Re: Trade-offs of templated implementations
On 9 Jun., 23:50, Olivier <olivier.gr...@gmail.com> wrote:
Hi All,
I'd like some comments on the pros and cons of three different
approaches of the same simple logic (best practice, code performance,
generated code, etc ...) :
1) Only runtime evaluation.
class MyClass
{
public:
MyClass( bool tof )
: tof_(tof)
{ }
void func0( int i )
{
if(tof_)
{
auto iter = std::lower_bound(ints_.begin(), ints_.end(),
i, std::less<int>());
// ...
}
else
{
auto iter = std::lower_bound(ints_.begin(), ints_.end(),
i, std::greater<int>());
// ...
}
}
private:
bool const tof_;
std::vector<int> ints_;
};
If you need both kinds to be the same type (i.e. you only know at
runtime), this is the way to go out of necessity.
If this algorithm is only a small part of the class, it's probably
also the way to go.
2) Compile-time evaluation.
template< bool ToF >
class MyClass
{
private:
template< typename Tp, bool >
struct Comp
{
bool operator()( Tp const &lhs, Tp const &rhs ) const
{ return lhs < rhs; }
};
template< typename Tp >
struct Comp<Tp,false>
{
bool operator()( Tp const &lhs, Tp const &rhs ) const
{ return lhs > rhs; }
};
public:
void func0( int i )
{
auto iter = std::lower_bound(ints_.begin(), ints_.end(),
i, Comp<int,ToF>());
// ...
};
private:
std::vector<int> ints_;
};
I would implement this as
auto iter = std::lower_bound(ints.begin(), ints.end(), i,
typename std::conditional<ToF, std::less<int>,
std::greater<int>>::type());
This has the advantage of being concise. There is probably no relevant
speed advantage over the purely runtime version, since in relation to
the lower_bound algorithm the single branch before it is quite
irrelevant.
3) Runtime branching based on a compile-time value. I take it most
compilers would remove the useless branch.
template< bool ToF >
class MyClass
{
public:
void func0( int i )
{
if(ToF)
{
auto iter = std::lower_bound(ints_.begin(),
ints_.end(), i, std::less<int>());
// ...
}
else
{
auto iter = std::lower_bound(ints_.begin(),
ints_.end(), i, std::greater<int>());
// ...
}
};
private:
std::vector<int> ints_;
};
This probably produces the same code as #2. But I don't like ifs based
on template parameters. Feels like a confusion of concepts to me.
Sebastian
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]