-1

So I was trying to write a default function version when there are no template arguments passed in the following code:

struct A{ int x; };

struct B : public A { int y;};

struct C {
    void set(const A& v) { v_ = v; }

    template <typename T>
    const T& get() { return reinterpret_cast<T&>(const_cast<A&>(v_)); }

    template <>
    const A& get() { return v_;}

    A v_;
};

int main() {
    B b;
    C c;
    c.set(b);
    (void)c.get<B>().y;
    (void)c.get<A>().x;
    //(void)c.get().x; << Error
}

But it doesn't work at the indicated Error line above with this error:

test.cpp:22:13: error: no matching member function for call to 'get'
    (void)c.get().x;
          ~~^~~
test.cpp:9:14: note: candidate template ignored: couldn't infer template argument 'T'
    const T& get() { return reinterpret_cast<T&>(const_cast<A&>(v_)); }
             ^
1 error generated.

I do understand the issue that since no template argument was passed in the client call, it was unable to infer the typename but is there a way to provide a default implementation like the one in the above code when that happens? Essentially I want to avoid writing client code as (void)c.get<A>().x; and instead, adopt the default route implicitly.

Zoso
  • 3,273
  • 1
  • 16
  • 27

2 Answers2

2

As an alternative solution, you can specify A as default template argument for parameter T, e.g.

struct C {
    void set(const A& v) { v_ = v; }

    template <typename T = A>
    const T& get() { return reinterpret_cast<T&>(const_cast<A&>(v_)); }

    template <>
    const A& get() { return v_;}

    A v_;
};

int main() {
    B b;
    C c;
    c.set(b);
    (void)c.get<B>().y; // call the primary template
    (void)c.get<A>().x; // call the specification
    (void)c.get().x;    // call the specification
}
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
1

You can delete the template <> part.

struct C {
    void set(const A& v) { v_ = v; }

    template <typename T>
    const T& get() { return reinterpret_cast<T&>(const_cast<A&>(v_)); }

    const A& get() { return v_;}

    A v_;
};
Stephen Newell
  • 7,330
  • 1
  • 24
  • 28