gct
gct

Reputation: 14573

Partially specializing template class in c++

I've got a template class:

template <typename T> struct randimpl {
    // default is to not compile, have to pass T to something to get assert
    // evaluated during second phase expansion, is_void is an arbitrary choice.
    static_assert(
        std::is_void<T>::value && false, "random() not implemented for type"
    );
};

This is just a proxy for a random() function that can be overloaded for user-defined types:

// random function, proxies request through randimpl
template <typename T> T random() {
    return randimpl<T>::random();
}

Which I'm trying to partially specialize for a type _point1d<T>:

// generate random instances _point1d<T>
template <typename T>
struct randimpl<_point1d<T>> {
    static _point1d<T> random() {
        return _point1d<T>(random<T>());
    }
};

Which as far as I can tell is the appropriate syntax, but when I compile, I get:

inc/geometry.h: In static member function ‘static _point1d<T> randimpl<_point1d<T> >::random()’:
inc/geometry.h:287:31: error: expected primary-expression before ‘(’ token
             return _point1d<T>(random<T>());
                               ^
inc/geometry.h:287:40: error: expected primary-expression before ‘>’ token
             return _point1d<T>(random<T>());
                                        ^
inc/geometry.h:287:42: error: expected primary-expression before ‘)’ token
             return _point1d<T>(random<T>());

Is my syntax off? This seems like it should work, but I don't understand why it's not accepting it.

Upvotes: 3

Views: 90

Answers (1)

songyuanyao
songyuanyao

Reputation: 172924

The problem is that the static member function's name random hides the global one, it's trying to invoke itself (i.e. recursive call). But it's not a template and doesn't match how it's called.

You can add :: (scope resolution) to specify the global random, e.g.

// generate random instances _point1d<T>
template <typename T>
struct randimpl<_point1d<T>> {
    static _point1d<T> random() {
        return _point1d<T>(::random<T>());
        //                 ^^
    }
};

LIVE

Upvotes: 3

Related Questions