Hello I am having difficulty with the decision I have made in coding. I am developing a game, and in my game I have treated everything in Object class and object class has two attributes mainly the vital attribute and point attribute. Point attribute somehow need to be in pair of string and int and sometimes float. (I don't use boost:variant I know it could have been much simpler as I have searched on this site) but I don't like to stick to the boost option, I really need to do this without it. So each point attribute object has int and floats on it, for example attack damage which, in my system is of type int, while attack rate is of type float. I came to solution to make a wrapper template class called PointAttribute< T > and this inherits on PABase class so I can make push it on to map without me knowing the type.
Now I am on the big question how do I properly access the second element of map with pair:
pair< string , PABase > ?
Is it even possible?
I did mine using this code
template< typename T >
PointAttribute< T > * Object::getPointAttributes( const string & oname )
{
PointAttribute< T > * attribute = static_cast< PointAttribute<T>* >( &pointAttributes[ oname ] );
cout << "Getting value of : " << oname << " value : " << attribute->getCurrentPoints() << endl;
return attribute;
}
I don't know if I am doing everything right. I know I am doing it wrong and I desperately need help on accessing the information from the second.
Actually my codes works but when I retrieved my desired value it returns a float with the wrong value. I've check the value of my point attribute definition and they seem to be loaded properly in my system it just that when I retrieved it returns a value which is of not the actual value I am expecting.
I invoked the function on this way
float attackRange = Object::getPointAttributes<float>( "attackrange" )->getCurrentPoints();
EDIT:
Here is my code for PABase and PointAttribute< T >:
#ifndef POINTATTRIBUTE_HPP
#define POINTATTRIBUTE_HPP
#include<iostream>
using std::cout;
using std::endl;
using std::cerr;
#include<string>
using std::string;
#include<memory>
using std::unique_ptr;
#include<SFML/Graphics.hpp>
namespace esc
{
class PABase{ public: virtual ~PABase(){} };
template< typename T >
class PointAttribute : public PABase
{
public:
PointAttribute();
virtual ~PointAttribute();
void setAttributePoints( T );
T getAttributePoints() const;
void increaseCurrentPointsBy( T );
void decreaseCurrentPointsBy( T );
void setCurrentPointsTo( T );
T getCurrentPoints() const;
void increaseMaxPointsBy( T );
void decreaseMaxPointsBy( T );
void setMaxPointsTo( T );
T getMaxPoints() const;
void increaseBasePointsBy( T );
void decreaseBasePointsBy( T );
void setBasePointsTo( T );
T getBasePoints() const;
void resetPointAttribute();
private:
void init();
string attributeName;
T attributePoints;
T currentPoints;
T maxPoints;
T basePoints;
};
template< typename T >
PointAttribute< T >::PointAttribute()
:
attributePoints( T() ),
currentPoints( T() ),
maxPoints( T() ),
basePoints( T() )
{
}
template< typename T >
PointAttribute< T >::~PointAttribute()
{
}
template< typename T >
inline void PointAttribute< T >::setAttributePoints( T p )
{
attributePoints = p;
currentPoints = p;
maxPoints = p;
basePoints = T();
cout << "\n\nAttribute set! " << endl;
cout << "Attribute points : " << attributePoints << endl;
cout << "Max points : " << maxPoints << endl;
cout << "Base points : " << basePoints << endl;
}
template< typename T >
inline T PointAttribute< T >::getAttributePoints() const
{
return attributePoints;
}
template< typename T >
inline void PointAttribute< T >::increaseCurrentPointsBy( T amount )
{
currentPoints += amount;
currentPoints = ( currentPoints > maxPoints )? maxPoints : currentPoints;
}
template< typename T >
inline void PointAttribute< T >::decreaseCurrentPointsBy( T amount )
{
currentPoints -= amount;
currentPoints = ( currentPoints < T() )? T() : currentPoints;
}
template< typename T >
inline void PointAttribute< T >::setCurrentPointsTo( T amount )
{
if( amount >= basePoints && amount <= maxPoints )
currentPoints = amount;
}
template< typename T >
inline T PointAttribute< T >::getCurrentPoints() const
{
return currentPoints;
}
template< typename T >
inline void PointAttribute< T >::increaseMaxPointsBy( T amount )
{
int checkVal = ( amount < T() )? T() : amount;
maxPoints += checkVal;
}
template< typename T >
inline void PointAttribute< T >::decreaseMaxPointsBy( T amount )
{
T checkVal = ( amount < T() )? T() : amount;
maxPoints -= checkVal;
}
template< typename T >
inline void PointAttribute< T >::setMaxPointsTo( T amount )
{
T checkVal = ( amount < T() )? T() : amount;
maxPoints = checkVal;
}
template< typename T >
inline T PointAttribute< T >::getMaxPoints() const
{
return maxPoints;
}
template< typename T >
inline void PointAttribute< T >::increaseBasePointsBy( T amount )
{
if( amount > T() && amount <= maxPoints )
basePoints += amount;
}
template< typename T >
inline void PointAttribute< T >::decreaseBasePointsBy( T amount )
{
if( amount > T() && amount <= maxPoints )
basePoints -= amount;
}
template< typename T >
inline void PointAttribute< T >::setBasePointsTo( T amount )
{
if( amount > T() && amount <= maxPoints )
basePoints = amount;
}
template< typename T >
inline T PointAttribute< T >::getBasePoints() const
{
return basePoints;
}
template< typename T >
inline void PointAttribute< T >::resetPointAttribute()
{
maxPoints = attributePoints;
basePoints = T();
}
}
#endif // POINTATTRIBUTE_HPP
Here is how the point attribute is beign filled up before the game begins. The definition is loaded from a simple text file with this given syntax:
[pointattribute]
attackdamage 7
attackrange 150
and here is the part of the home-made reader I have made, what this does is to read a particular identifier as long it is a valid file symbol, in this case [pointattribute]
the reason is I could add more point attribute in the future without doing a lot of codes and I can just change them freely as I balance the game. (I am writing a framework for RTS).
Here is the snippet for that else-if part of the reader
else if( identifier.compare("[pointattribute]") == 0 )
{
string aname;
string s_eval;
s >> aname >> s_eval;
cout << "\n\nLoading point attribute of : " << oname << endl;
cout << "Attribute name : " << aname << " value : ";
if( is< float >( s_eval ) )
{
istringstream s( s_eval );
float fval = 0.0f;
s >> fval;
PointAttribute< float > wrap;
wrap.setAttributePoints( fval );
attrib->pointAttributes[ aname ] = wrap;
cout << fval << endl;
}
else if( is< int >( s_eval ) )
{
istringstream s( s_eval );
int ival = 0;
s >> ival;
PointAttribute< int > wrap;
wrap.setAttributePoints( ival );
attrib->pointAttributes[ aname ] = wrap;
cout << ival << endl;
}
}
The value returned in Object class scope is on around 1.0e something whatever. It just return that kind of real number which is in fact not the value I am expecting. Something is wrong and something I gravely overlooked.
Also I have a young experience in C++ so sorry for my jargons I hope I made myself clear. Thanks for your help.
Related
I am trying to use templates to represent simple polynomials like x^2 + 3x + 5. My idea is to represent them as sum of terms with each term having a coefficient and a power so e.g. x^2 has coeff=1 and power=2. I also want to be able to evaluate the polynomials for some x (they only have 1 unknown but in many places). So far I have:
struct PolyEnd{
double eval(double x){
return 0;
}
};
template <int coeff, int power, class Tail> struct Poly {
typedef Tail tt;
double eval(double x){
double curr = coeff * std::pow(x, power);
return curr; // has to call eval(x) on rest of the terms which are in the tail and return the sum with "curr"
}
};
int main()
{
double x = 2;
Poly<1,1,Poly<1,1,PolyEnd>> poly;
std::cout << poly.eval(x) << std::endl;
return 0;
}
However, I am stuck. Is what I am trying even possible? If so how can I make the recursive eval() calls work?
Yes, you can do that, you just need to call eval on the tail and since all the classes are state-less, you can just create an instance to call the member function on, on the spot:
struct PolyEnd{
double eval(double x){
return 0;
}
};
template <int coeff, int power, class Tail> struct Poly {
typedef Tail tt;
double eval(double x){
double curr = coeff * std::pow(x, power);
return curr + Tail{}.eval(x);
}
};
int main()
{
double x = 2;
Poly<1,1,Poly<1,1,PolyEnd>> poly;
std::cout << poly.eval(x) << std::endl;
return 0;
}
or if you make eval static, then you can call Tail::eval(x) directly.
I guess that you are experimenting with metaprogramming. Your question also made me excited, because i am also newbie in metaprogramming and I want to practise. #walnut's answer already accepted but there is no harm to share another implementation. I used some basic metaprogramming techniques.
I hope it will help you.
#include <cmath>
#include <iostream>
#include <string>
template<int Value>
struct coeff
{ };
template<int Value>
struct power
{ };
template<typename Coefficient, typename Power>
struct term;
template<int Coefficient , int Power>
struct term< coeff<Coefficient> , power<Power> >
{
inline double eval( double x ) const noexcept {
return Coefficient * std::pow( x , Power );
}
};
template<int Value>
using constant = term< coeff<Value> , power<1> >;
template<int Value>
using exponential = term< coeff<1> , power<Value> >;
template<typename... T>
struct polynomial
{
static_assert( sizeof...(T) == 0, "A polynomial can only be expressed in 'term's.");
[[nodiscard]] constexpr double eval( double ) const noexcept {
return 0;
}
[[nodiscard]] std::string to_string() const noexcept {
return std::string{};
}
};
template<int Coefficient, int Power, typename... Tail>
struct polynomial<term< coeff<Coefficient> , power<Power> >, Tail...>
: polynomial<Tail...>
{
[[nodiscard]] constexpr double eval( double x ) const noexcept {
return m_t.eval( x ) + polynomial<Tail...>::eval( x );
}
[[nodiscard]] std::string to_string(){
using namespace std;
using namespace std::string_literals;
return "("s + std::to_string( Coefficient ) +
string { "x^" } +
std::to_string( Power ) + ( sizeof...(Tail) == 0 ? ")" : ") + " ) +
polynomial<Tail...>::to_string();
}
private:
term< coeff<Coefficient> , power<Power> > m_t;
};
int main()
{
auto p1 = polynomial<term< coeff<1> , power<2> > ,
term< coeff<2> , power<4> > ,
term< coeff<2> , power<3> > ,
constant<3> ,
exponential<2> >{};
std::cout << "Polynomial is : " << p1.to_string() << std::endl;
std::cout << "f(2) : " << p1.eval( 2 ) << std::endl;
std::cout << "f(3) : " << p1.eval( 3 ) << std::endl;
return 0;
}
run online
Polynomial coefficients can be stored in std::array or std::vector(in case you define polynomial degree in runtime).
Then extend functionality with eval function.
template <unsigned N>
class Poly : public std::array<double, N> {
public:
template <typename... E>
Poly(E &&... e) : std::array<double, N>{{std::forward<E>(e)...}} {}
double eval(double x) {
double result = 0;
double exp = 1.;
for (auto it = this->rbegin(); it != this->rend(); ++it) {
result += exp * (*it);
exp *= x;
}
return result;
}
};
usage
double result = Poly<3>{3., 2., 1.}.eval(17);
I have a problem with the following class. I get error "Tree.cpp:12:56: error: type/value mismatch at argument 2 in template parameter list for ‘template class std::multiset’ // Tree.cpp:12:56: note: expected a type, got ‘(Tree::compare < )’". I don't understand how I should pass the comparator type in the multiset declaration. Could you help me?
#include <set>
#include <deque>
#include <iostream>
using namespace std;
template <typename T>
class Tree
{
typedef typename std::multiset<Tree<T>*, typename Tree<T>::compare > NodeSet;
private:
NodeSet children;
T content;
public:
struct compare
{
bool operator()( const Tree*& t1, const Tree*& t2 ) const
{
cout << "Comparing " << t1->GetContent() << " vs " << t2->GetContent() << endl;
return t1->GetContent() < t2->GetContent();
}
};
Tree& AppendNode( const T& node )
{
Tree* t = new Tree( node );
AttachTree( t );
return *t;
}
void Clear()
{
typename NodeSet::iterator it = children.begin();
while( children.size() != 0 && children.end() != it )
{
children.erase( *it );
delete *it;
it++;
}
}
Tree( const T& root )
{
content = root;
}
void AttachTree( Tree* t )
{
children.insert( t );
}
void Visit( std::deque<T>& exp ) const
{
exp.push_back( content );
typename NodeSet::iterator it = children.begin();
while( it != children.end() )
{
( *it )->Visit( exp ); it++;
}
}
Tree()
{}
Tree( Tree& c )
{
c.DeepCopyTo( this );
}
T& operator =( const Tree& b )
{
b.DeepCopyTo( this );
}
~Tree()
{
cout << "in destructor for" << this << endl;
Clear();
}
void DeepCopyTo( Tree* dest ) const
{
dest->content = content;
typename NodeSet::iterator it = children.begin();
while( it != children.end() )
{
Tree* t = new Tree();
( *it )->DeepCopyTo( t );
dest->AttachTree( t );
it++;
}
}
void Print()
{
typename NodeSet::iterator it = children.begin();
while( it != children.end() )
{
cout << *it << ",";
it++;
}
}
};
int main()
{
Tree<int> tree( 8 );
tree.AppendNode( 5 );
}
You might want to change this line to
typedef
typename std::multiset<Tree*, typename Tree::compare >
NodeSet;
Note that compare is a dependent name, so you need to use typename.
Also, you should consider moving the struct compare above this line, as this line references it.
Two more things to notice.
You might want to change compare to
struct compare {
bool operator()(const Tree* t1, const Tree* t2) const {
cout << "Comparing " <<t1->GetContent() <<" vs "<<t2->GetContent()<<endl;
return t1->GetContent() < t2->GetContent();
}
};
unfortunately, GetContent doesn't seem defined anywhere in your code.
As continue of thread Compare of std::function with lambda
I have problem with capture this to lambda - and compare after that with "correct callback".
#include <iostream>
#include <functional>
using namespace std;
//////////////////////////////////////////////////////////////////////////
class IFoo
{
public:
virtual void onAppStarted( int, int ) = 0;
};
//////////////////////////////////////////////////////////////////////////
template <typename T>
struct FunctionTypeDeduction;
template<class ClassType, class ReturnType, class... Args>
struct FunctionTypeDeduction< ReturnType( ClassType::* )( Args... ) >
{
using type = ReturnType( *)( Args... );
using functorType = std::function<ReturnType( Args... ) >;
};
//////////////////////////////////////////////////////////////////////////
class SubcribeSystem
{
public:
using tSomeMethodType = FunctionTypeDeduction< decltype( &IFoo::onAppStarted ) >::type;
using tSomeMethodCallback = FunctionTypeDeduction< decltype( &IFoo::onAppStarted ) >::functorType;
public:
void subribeOnSomeMethod( const tSomeMethodCallback& arr )
{
arr( 3, 19 );
}
};
#define SUBCRIBE_FOR_SOMEMETHOD( eventsObj, lambda ) \
do \
{ \
SubcribeSystem::tSomeMethodType const func_ptr = lambda; \
eventsObj.subribeOnSomeMethod( lambda ); \
} \
while(false);
//////////////////////////////////////////////////////////////////////////
class Bar
{
public:
void fn( SubcribeSystem& events )
{
auto onAppStart = []( int width, int height )
{
cout << width << " " << height << endl;
};
auto onAppStart2 = []( bool width, int height )
{
cout << width << " " << height << endl;
};
auto onAppStart3 = [this]( int width, int height )
{
cout << width << " " << height << endl;
someOtherMethod( width );
};
SUBCRIBE_FOR_SOMEMETHOD( events, onAppStart ); // expect all ok
//SUBCRIBE_FOR_SOMEMETHOD( events, onAppStart2 ); // expect error cause bool first param
SUBCRIBE_FOR_SOMEMETHOD( events, onAppStart3 ); // expect all ok, but not !!!
}
void someOtherMethod( int x )
{
cout << "processed callback " << x << endl;
}
};
int main()
{
Bar bar;
SubcribeSystem sub;
bar.fn( sub );
}
In your macro you have
SubcribeSystem::tSomeMethodType const func_ptr = lambda;
Where SubcribeSystem::tSomeMethodType is a
FunctionTypeDeduction< decltype( &IFoo::onAppStarted ) >::type
which is a function pointer. So you are trying to convert the lambda into a function pointer. Unfortunately a lambda that captures, which onAppStart3 does, cannot be converted to a function pointer.
The first two lambdas work as they do not capture so they have an implicit function pointer conversion operator.
How can I create one comparator to compare on different fields. Different fields can have different types (uint or string). Should I use T *?
It is necessary to reduce the code length.
template<typename T>
class ComparatorSelector
{
public:
struct CompareByLabel{
bool operator() ( const T & iRight, const T & iLeft )
{
return iRight->m_label > iLeft->m_label;
}
};
struct CompareByHouseNumber{
bool operator() ( const T & iRight, const T & iLeft )
{
return iRight->m_houseNumber > iLeft->m_houseNumber;
}
};
//...
};
template< class T, class C, typename W >
class SearchIndex
{
public:
SearchIndex() {}
void Build( std::vector< T > iElems, C iComparator, std::ofstream oStream )
{
std::map< T *, size_t> numbersOfElems;
for( class std::vector<T>::iterator it = iElems.begin(); it != iElems.end(); ++it){
m_elems.insert( &(*it));
numbersOfElems[&(*it)] = m_elems.end - it ;
}
oStream << m_elems.size();
for( class std::multiset< T * >::iterator it = m_elems.begin(); it!= m_elems.end(); ++it )
oStream << numbersOfElems[*it];
m_compareMode = iComparator;
}
//....
}
You can use pointers to members to customize your comparator objects. The slower but simpler approach is this:
#include <iostream>
template <typename Type, typename Class>
class comparator
{
Type Class::*d_member;
public:
comparator(Type Class::*member): d_member(member) {}
bool operator()(Class const& object0, Class const& object1) const {
return object0.*(this->d_member) < object1.*(this->d_member);
}
};
template <typename Type, typename Class>
comparator<Type, Class>
make_comparator(Type Class::*member)
{
return comparator<Type, Class>(member);
}
int main()
{
typedef std::pair<int, double> pair;
pair p0(17, 3.14);
pair p1(42, 2.7);
std::cout << std::boolalpha
<< "first: " << make_comparator(&pair::first)(p0, p1) << ' '
<< "second: " << make_comparator(&pair::second)(p0, p1) << ' '
<< '\n';
}
Since this version uses a pointer to member at run-time, it cannot be easily inlined and, thus, isn't as fast as you'd possibly want it to be. The member can also be embedded into the comparator's type making both its use a bit annoying:
template <typename Type, typename Class, Type Class::*Member>
class comparator
{
public:
bool operator()(Class const& object0, Class const& object1) const {
return object0.*Member < object1.*Member;
}
};
int main()
{
typedef std::pair<int, double> pair;
pair p0(17, 3.14);
pair p1(42, 2.7);
std::cout << std::boolalpha
<< "first: " << comparator<int, pair, &pair::first>()(p0, p1) << ' '
<< "second: " << comparator<double, pair, &pair::second>()(p0, p1) << ' '
<< '\n';
}
This is an example of a comparator that uses different fields of different types:
#include <set>
using namespace std;
class House {
public:
string m_label;
int m_houseNumber;
};
class HouseCompare {
public:
bool operator()( const House& a, const House& b)
{
if (a.m_houseNumber>0 && b.m_houseNumber>0)
return a.m_houseNumber < b.m_houseNumber;
else if (a.m_houseNumber>0)
return false;
else if (b.m_houseNumber)
return true;
else
return a.m_label < b.m_label;
}
};
int main(int argc, char *argv[])
{
typedef multiset<House, HouseCompare> Houses;
Houses houses;
House house_data[] = {
{"foo", 1},
{"foo1", 0},
{"foo0", 0},
{"foo", 2}
};
houses.insert (house_data, house_data+sizeof(house_data)/sizeof(House));
for (Houses::iterator i = houses.begin (); i != houses.end (); ++i)
cout << i->m_houseNumber << ": " << i->m_label << endl;
return 0;
}
Output:
0: foo0
0: foo1
1: foo
2: foo
The goal of the code below is to implement a histogram where the bucket limits are template parameters:
#include <iostream>
#include <limits>
#include "histogram.h"
int main ( int argc, char* argv[] )
{
//histogram_tuple<5,10,15,std::numeric_limits<int>::max()> histogram;
histogram_tuple<5,10,15> histogram;
histogram.count ( 9 );
histogram.count ( 10 );
histogram.count ( 11 );
histogram.count ( 15 );
std::cout << sizeof ( histogram ) << std::endl;
std::cout << '<' << histogram.limit() << ' ' << histogram.count() << ", "
<< '<' << histogram.rest().limit() << ' ' << histogram.rest().count() << ", "
<< '<' << histogram.rest().rest().limit() << ' ' << histogram.rest().rest().count() << ", "
<< ' ' << histogram.rest().rest().rest().count()
<< std::endl;
std::cout << "====" << std::endl;
std::cout << '<' << bucket_limit<0>(histogram) << ':'
<< bucket_count<0>(histogram) << std::endl;
std::cout << '<' << bucket_limit<1>(histogram) << ':'
<< bucket_count<1>(histogram) << std::endl;
std::cout << '<' << bucket_limit<2>(histogram) << ':'
<< bucket_count<2>(histogram) << std::endl;
// std::cout << '<' << bucket_limit<3>(histogram) << ':'
// << bucket_count<3>(histogram) << std::endl;
}
The above works fine. With the repeated rest() calls, the count of the final bucket (values >= 15) is printed.
However, when the final line of main() is uncommented, g++ 4.7.1 generates a compiler error that bucket_limit_entry<0u> and bucket_count_entry<0u> are incomplete.
Any advice on how to get the convenience functions bucket_limit<3> to compile, since the repeated rest() calls work?
Not really sure what's going on. Changing the index type to int and making the termination case -1 instead of 0 didn't work.
Here's histogram.h:
#pragma once
template <int ... Limits>
class histogram_tuple;
template<>
class histogram_tuple<>
{
int cnt_;
public:
histogram_tuple<>() :
cnt_ ( 0 )
{
}
void count ( int value )
{
++cnt_;
}
int count() const
{
return cnt_;
}
};
template <int First, int ... Rest>
class histogram_tuple <First,Rest...> :
private histogram_tuple<Rest...>
{
static const int limit_ = First;
int cnt_;
public:
histogram_tuple <First,Rest...>() :
cnt_ ( 0 )
{ }
int limit() const { return limit_; }
void count ( int value )
{
if ( value < limit_ )
++cnt_;
else
rest().count ( value );
}
int count() const
{
return cnt_;
}
const histogram_tuple<Rest...>& rest() const
{
return *this;
}
histogram_tuple<Rest...>& rest()
{
return *this;
}
};
template <unsigned index, int ... Limits>
struct bucket_count_entry;
template <int First, int ... Limits>
struct bucket_count_entry<0,First,Limits...>
{
static int value(histogram_tuple<First,Limits...> const& histogram)
{
return histogram.count();
}
};
template <unsigned index,int First, int ... Limits>
struct bucket_count_entry<index,First,Limits...>
{
static int value(histogram_tuple<First,Limits...> const& histogram)
{
return bucket_count_entry<index-1,Limits...>::value(histogram.rest());
}
};
template <unsigned index,int ... Limits>
int bucket_count( histogram_tuple<Limits...> const& histogram )
{
return bucket_count_entry<index,Limits...>::value(histogram);
}
template <unsigned index, int ... Limits>
struct bucket_limit_entry;
template <int First, int ... Limits>
struct bucket_limit_entry<0,First,Limits...>
{
static int value(histogram_tuple<First,Limits...> const& histogram)
{
return histogram.limit();
}
};
template <unsigned index,int First, int ... Limits>
struct bucket_limit_entry<index,First,Limits...>
{
static int value(histogram_tuple<First,Limits...> const& histogram)
{
return bucket_limit_entry<index-1,Limits...>::value(histogram.rest());
}
};
template <unsigned index,int ... Limits>
int bucket_limit( histogram_tuple<Limits...> const& histogram )
{
return bucket_limit_entry<index,Limits...>::value(histogram);
}
template <int First, int ... Limits>
bucket_limit_entry<0,First,Limits...>
won't match
bucket_limit_entry<0>
because First won't match nothing. (...Limits matches nothing, but First can only match one int).
So you need to add an additional template for the case where you've run out of limits:
template<>
struct bucket_limit_entry<0>
When you do that, you'll find that histogram<>::limit() is undefined, but you can easily fix that.
You'll need to do the same with bucket_count_entry, except that histogram<>::count() is defined.
The fact that you can't just define template<int...Limits> struct bucket_limit_entry<0, Limits...> {...} is a bit odd. The problem, as I understand it, is that both "Index is 0" and "Limits... has at least one element", are restrictions on the general template, and there is no arbitrary ordering between them. Consequently, template<int...Limits> struct X<0, Limits...> and template<unsigned index, int First, int...Rest> struct X<index, First, Rest...> are not ordered by the partial ordering for template specialization, and when both of them apply, you end up with an ambiguity.
But it seems to me that there is a simpler solution, since you can let the type of the histogram_tuple just be deduced:
template<unsigned Index> struct bucket_limit_entry {
template<typename Hist>
static int value(Hist const& histogram) {
return bucket_limit_entry<Index-1>::value(histogram.rest());
}
};
template<> struct bucket_limit_entry<0> {
template<typename Hist>
static int value(Hist const& histogram) {
return histogram.limit();
}
};
template<unsigned index, typename Hist>
int bucket_limit(Hist const& histogram ) {
return bucket_limit_entry<index>::value(histogram);
}