C++ Template Problem

camelCase

The Case of the Mysterious Camel.
Reaction score
362
All right, so it's been a long time since I used C++.. And even longer since I used templates. I understand that I may be using templates in a weird way, if you'll look at the two bits of code below, but I assure you that I have a valid reason for doing so =P

I encountered a problem and decided to reduce my code to the simplest form that produces the error. Here are the results.

This compiles:
Code:
template <class T>
class Bar {};
 
template<class T, class Dummy=void>
class Foo;
 
template<class T>
class Foo <T, typename std::enable_if<
    std::is_base_of<Bar<T>, T>::value
>::type> {
    public:
        //THIS CHANGES IN THE 2ND SNIPPET
        void test () const {
            std::cout << "test";
        }
};
 
class Cat : Bar<Cat> {};
 
int main () {
    Foo<Cat> foo;
    foo.test();
    return 0;
}

This errors:
Code:
template <class T>
class Bar {};
 
template<class T, class Dummy=void>
class Foo;
 
template<class T>
class Foo <T, typename std::enable_if<
    std::is_base_of<Bar<T>, T>::value
>::type> {
    public:
        //THIS CHANGED!
        void test () const;
};
 
//THIS WAS ADDED SINCE THE 1ST SNIPPET!
template<class T>
void Foo<T>::test () const {
    std::cout << "test";
} //error C2039: 'test' : is not a member of 'Foo<T>'
 
class Cat : Bar<Cat> {};
 
int main () {
    Foo<Cat> foo;
    foo.test();
    return 0;
}

I have marked the differences. Why does it error in the 2nd code snippet? How do I keep declaration and definition separate while avoiding the error?

I'm guessing it's got something to do with this:
"template<class T>
void Foo<T>::test () const"

Like, this is the wrong way to tell the compiler that the method [ljass]test() const[/ljass] is a method of template class [ljass]template<class T>
class Foo <T, typename std::enable_if<
std::is_base_of<Bar<T>, T>::value
>::type>[/ljass]
 

camelCase

The Case of the Mysterious Camel.
Reaction score
362
Oh, never mind. Got the answer. I'm supposed to define it like this..
Code:
template<class T>
void Foo<T, typename std::enable_if<
    std::is_base_of<Bar<T>, T>::value
>::type>::test () const {
    std::cout << "test";
}

You'll notice that the [ljass]std::enable_if<>[/ljass] from the class declaration also has to be in the method definitions.. Oh, gawd.. So verbose..
 

s3rius

Linux is only free if your time is worthless.
Reaction score
130
Some call template metaprogramming the cancer of C++ =)
 

camelCase

The Case of the Mysterious Camel.
Reaction score
362
Yes.. I can sort of see why..
But when it works, god, damn, it works.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top