1

I'm trying to do something like this:

#include <iostream>
#include <array>
using namespace std;

template <size_t A>
class Test {
    public:
        typedef array<int, A> TestType;
};

template <size_t A>
void foo(Test<A>::TestType t) {
    cout << "test\n";
}

int main() {
    Test<5>::TestType q;

    foo(q);
    return 0;
}

but foo doesn't compile. In gcc I get

prog.cpp:12:19: error: variable or field ‘foo’ declared void
 void foo(Test<A>::TestType t) {
                   ^
prog.cpp:12:28: error: expected ‘)’ before ‘t’
 void foo(Test<A>::TestType t) {

while in Visual Studio 2010 I get

error C2975: 'Test' : invalid template argument for 'A', expected compile-time constant expression

I don't understand what I am doing wrong, as A is a compile-time constant. What should I change?

Svalorzen
  • 5,353
  • 3
  • 30
  • 54

1 Answers1

1

If you would add typename like this:

template <size_t A>
void foo(typename Test<A>::TestType t) {
    cout << "test\n";
}

the only effect is a better error message. The problem is that you still can not deduce template parameters like that.

When you declare q

Test<5>::TestType q;

q's type is std::array<int,5> and the compiler doesn't know how this type was connected to Test<5>. In the call to foo(q) it would need a much deeper analysis of the code which is not standardized to figure out that there is only one possible match for A. You need to call

foo<5>(q);

to specify it explicitly or change the definition of foo:

template <size_t A>
void foo(std::array<int,A> t) {
    cout << "test\n";
}
Daniel Frey
  • 55,810
  • 13
  • 122
  • 180