5

Please throw some light on that baffling piece of template spaghetti:

template <typename T, typename K> class A {
public:
    T t;
    K k;

    template <int i, int unused = 0> struct AttributeType {
    };

    template <int i> AttributeType<i> getAttr();

};

template <typename T, typename K> template <int i> A<T, K>::AttributeType<i> A<T, K>::getAttr<i>() {
    return t;
}

I'm not able to come up with the correct syntax to define the implementation of A::getAttr(). The current code fails to compile at the line of getAttr definition:

error: function template partial specialization ‘getAttr<i>’ is not allowed

How should I rephrase the function definition?

ognian
  • 11,451
  • 4
  • 35
  • 33
  • As a side note, rather than an answer, things are much simpler in general if you *define* the members of a template in place, rather than pulling them outside of the template definition. That is, it would be much simpler if `getAttr` was defined where it is being declared. – David Rodríguez - dribeas Jun 03 '11 at 21:03

1 Answers1

7

Remove that <i> behind the function name and add a typename right before the return type, it's a dependent name. Also, it's missing a template before AttributeType because that's a template:

template <typename T, typename K>
template <int i>
typename A<T, K>::template AttributeType<i> A<T, K>::getAttr() {
    return t;
}

Next, it is helpful to give each template part its own line. Makes stuff clearer.

Aside from that, the function looks wrong, or does AttributeType have a conversion constructor from T?

Xeo
  • 129,499
  • 52
  • 291
  • 397
  • Wow, thanks! You're a true compiler-head :) I just had to add `template` before `AttributeType` and it worked: – ognian Jun 03 '11 at 20:12
  • @ognian: Not `template`, `typename`. See [this FAQ](http://stackoverflow.com/questions/610245/where-and-why-do-i-have-to-put-template-and-typename-on-dependent-names). – Xeo Jun 03 '11 at 20:14
  • @Xeo: template *and* typename: `template template typename A::template AttributeType A::getAttr() { return t; }` – ognian Jun 03 '11 at 20:15
  • @ognian: Interesting, VC10 fails to compile with `template`. Brb. – Xeo Jun 03 '11 at 20:16
  • @ognian: This is bothering me, so please take a look at [this follow-up question](http://stackoverflow.com/questions/6232294/which-compiler-is-right-template-before-templated-return-type-needed). :) – Xeo Jun 03 '11 at 20:26
  • @ognian: I'll trust GCC and Comeau for now and edit the `template`, for correctness' sake. – Xeo Jun 03 '11 at 20:35