Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

specializing member S::display requires ‘template<>’ syntax

Tags:

c++

I'm creating a trait class to help with my program. I have a template class called operations that contains the methods display and area. When I define these functions I get errors. Here they are:

error: specializing member ‘traits::operations<Rectangle>::display’ requires ‘template<>’ syntax
error: specializing member ‘traits::operations<Rectangle>::area’ requires ‘template<>’ syntax

As you can see, the compiler wants me to insert template <> just before those definitions. But when I do, I get a huge page of errors. What's going wrong and how can I fix it?

Here is my program.

namespace traits
{
    template <typename P>
    struct operations
    {
        static void display(Rectangle const &, std::ostream &);
        static void area(Rectangle const &);
    };

    template <typename P, int N>
    struct access {};
}

namespace traits
{
    template <int N>
    struct access<Rectangle, N>
    {
        static double get(Rectangle const &);
    };
}

// The errors occur here
namespace traits
{
    static void operations<Rectangle>::display(Rectangle const &rect, std::ostream &os)
    {
        os << rect.width  << '\n';
        os << rect.height << '\n';
        os << area(rect)  << '\n'; 
    }

    static void operations<Rectangle>::area(Rectangle const& rect)
    {
        double width =  get<0>(rect);
        double height = get<1>(rect);

        return width * height;
    }
}

namespace traits
{
    template <>
    struct access<Rectangle, 0>
    {
        static double get(Rectangle const &rect)
        {
            return rect.width;
        }
    };

    template <>
    struct access<Rectangle, 1>
    {
        static double get(Rectangle const &rect)
        {
            return rect.height;
        }
    };
}

template <int N, typename P>
static inline double get(P const &p)
{
    return traits::access<P, N>::get(p);
}

template <typename P>
static inline void display(P const &p)
{
    traits::operations<P>::display(p, std::cout);
}

template <typename P>
static inline double area(P const &p)
{
    return traits::operations<P>::area(p);
}

int main()
{

}

Here is a program which shows the error - http://ideone.com/WFlnb2#view_edit_box

Any and all help is appreciated.


Thanks to help from the comments I got rid of those two errors, but I'm not getting more after adding the template<> declaration and fixing the return type of area:

error: cannot declare member function ‘static void traits::operations<P>::display(const Rectangle&, std::ostream&) [with P = Rectangle; std::ostream = std::basic_ostream<char>]’ to have static linkage [-fpermissive]
error: explicit template specialization cannot have a storage class
error: specialization of ‘static double traits::operations<P>::area(const Rectangle&) [with P = Rectangle]’ after instantiation
error: explicit template specialization cannot have a storage class

like image 544
template boy Avatar asked May 11 '13 02:05

template boy


2 Answers

Your functions : display and area should be write like this:

    template <>
    double operations<Rectangle>::area( Rectangle const& rect )
    {
            double width =  get<0>(rect);
            double height = get<1>(rect);

            return width * height;
    }
  • As for template specialized functions, template <> should be placed at the head of the function.
  • For static member functions, static should not appear at the definition body of the function.
like image 66
prehistoricpenguin Avatar answered Oct 27 '22 00:10

prehistoricpenguin


template< typename P > // P is declared here
struct operations  {
    ... // into this scope
}; // but it goes out of scope here

template< typename P > // So it needs to be redeclared
void operations::display( Rectangle const &, std::ostream &) {
    ... // for this scope.
}

The function display doesn't "own" the names of its parameters. The template parameter must be redeclared in the definition. The compiler message is referring to template<> syntax to suggest you place something inside the <> brackets, but confusingly, leaving the brackets empty and literally saying template<> means something else — explicit specialization, which isn't what you want here.

On the other hand, static is a property of a member function which does not get mentioned in the definition. The compiler remembers static after using the other parts of the definition signature to match it to the declaration signature. So, you should erase static from the definition.

like image 41
Potatoswatter Avatar answered Oct 27 '22 00:10

Potatoswatter