0

Possible Duplicate:
Where and why do I have to put the “template” and “typename” keywords?

There appears to be a bug in GCC 4.5.3:

#include <type_traits>

template <bool isFundamentalType, bool isSomething>
struct Foo
{
    template <typename T>
    static inline void* Do(size_t size);
};

template <>
struct Foo<true, false>
{
    template <typename T>
    static inline void* Do(size_t size)
    {
        return NULL;
    }
};

template <>
struct Foo<false, false>
{
    template <typename T>
    static inline void* Do(size_t size)
    {
        return NULL;
    }
};

class Bar
{
};

template <typename T>
int Do(size_t size)
{
    // The following fails
    return (int) Foo<std::is_fundamental<T>::value, false>::Do<T>(size);
    // This works -- why?
    return (int) Foo<false, false>::Do<T>(size);
}

int main()
{
    return Do<Bar>(10);
}

Compiled with g++ bug.cpp -std=c++0x

Errors:

bug.cpp: In function ‘int Do(size_t)’:
bug.cpp:37:65: error: expected primary-expression before ‘>’ token

Is there a known workaround that would allow me to side step this issue?

EDIT: MSVC 2010 managed to compile this just fine.

Community
  • 1
  • 1
Zach Saw
  • 4,308
  • 3
  • 33
  • 49

1 Answers1

2

You need to add template:

return (int) Foo<std::is_fundamental<T>::value, false>::template Do<T>(size);

MSVC 2010 compiles the code because it doesn't handle templates correctly.

Side Note

MSVC also injects size_t into the global namespace because of a long withstanding bug. Technically you need to include the proper header on other compilers.

Jesse Good
  • 50,901
  • 14
  • 124
  • 166
  • `#include ` already does that. Someone was trying to be funny and screwed up my post by editing it. – Zach Saw Oct 31 '12 at 04:37
  • 1
    Why does this work though - `return (int) Foo::Do(size);` – Zach Saw Oct 31 '12 at 04:37
  • 1
    @ZachSaw Foo isn't dependent on the template parameters there I believe. – Pubby Oct 31 '12 at 04:39
  • @ZachSaw: In your second example, the compiler *knows* that `Do` is a template member function, however in your first example, it doesn't know that `Do` is a member template because the interpretation depends on `std::is_fundamental::value`. Also, `#include ` does not have `size_t`. As seen [here](http://liveworkspace.org/code/c56fc3838e1f574cb339d7da8fe68039): `error: 'size_t' was not declared in this scope`. – Jesse Good Oct 31 '12 at 04:46
  • @JesseGood: But GCC 4.5.3 compiles the example perfectly fine? – Zach Saw Oct 31 '12 at 04:48
  • @ZachSaw: That was fixed in gcc 4.6. See [here](http://gcc.gnu.org/gcc-4.6/porting_to.html) and read `Header dependency changes`. – Jesse Good Oct 31 '12 at 04:52
  • @Zach: I didn't "try to be funny", I just edited your post since it's nothing C++11 specific, just because you used `` and I forgot about the `size_t`. Also, `` does *not* inject `size_t` into the global namespace. – Xeo Oct 31 '12 at 05:05
  • @Xeo: I wouldn't mind if you removed C++11 tag, but you didn't have to edit my code. Just saying. – Zach Saw Oct 31 '12 at 05:47