Sign in to follow this  
Sent1nel

Boost enable_if, Help Required

Recommended Posts

I am trying to use boost enable_if for a vector class of which can be set to be of various dimensions. I want to be able to hide specific constructors and functions of which do not apply to all types of vector. The error I am getting is related to the std::size_t in the example below. Could someone show me how to use enable_if? example

template < std::size_t N = 3, typename T = float >
class Vector
{
    Vector(const T &x);
    Vector(const T &x, const T &y);
    Vector(const T &x, const T &y, const T &z);  
    Vector(const T &x, const T &y, const T &z, const T &w);
}




Share this post


Link to post
Share on other sites
What error are you getting? boost::enable_if/disable_if rely on SFINAE, which means that you need to create a situation in which the compiler won't be able to perform the substitution. For instance:

Vector(const typename boost::enable_if<N==1,T>::type& x);
Vector(const typename boost::enable_if<N==2,T>::type& x, const typename boost::enable_if<N==2,T>::type& y);


If N isn't the appropriate values, the enable_if structures don't have type, and the compiler ignores the function definition.

Share this post


Link to post
Share on other sites
Sorry nipped away for some dinner.

The error I am getting if I implement what you just described is

: error C2955: 'boost::enable_if' : use of class template requires template argument list

: error C2974: 'boost::enable_if' : invalid template argument for 'Cond', type expected




template < std::size_t N = 3, typename T = float >
class Vector
{
Vector(const typename boost::enable_if<N==1,T>::type &x);
Vector(const T &x, const T &y);
Vector(const T &x, const T &y, const T &z);
Vector(const T &x, const T &y, const T &z, const T &w);
}



I tried inserting the typename boost::enable_if<N==1,T>::type into both the declartion and the actual constructor function.

Share this post


Link to post
Share on other sites
Er, yes, my bad, try boost::enable_if_c. The first template argument to boost::enable_if actually takes a type that needs a static boolean constant named value. If you wanted, you could use boost::integral_constant<bool, N==1>, which is probably better since it makes your code compatible with the MPL.

Share this post


Link to post
Share on other sites
I also just tried the boost::enable_if_c, and it compiles but not builds. I get external linker errors.

error LNK2019: unresolved external symbol "public: __thiscall Engine::Maths::Vector<3,float>::Vector<3,float>(float const &,float const &,float const &)" (??0?$Vector@$02M@Maths@Engine@@QAE@ABM00@Z) referenced in function _main Main.obj

:'(

Share this post


Link to post
Share on other sites
Quote:
Original post by theOcelot
The definitions of the functions will need to be visible where they're used, if I'm not mistaken. That probably means the whole class will need to be in the header.

Indeed, since it's a template class, everything needs to be in the header (additional reading). The linker error is simply because you haven't defined the constructor.

Share this post


Link to post
Share on other sites
I moved everything into the class declaration just to make sure it was not that casuing the problems.( I was using a .inl file before splitting the class from the functions ). It's still throwing compile errors. It's not saying "no such thing as type" in enable_if_c, which would mean the boolean condition is getting set as false.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this