Re: template problem: local variable as non-type argument
On 5 Feb., 09:34, "vl106" <vl...@hotmail.com> wrote:
I know the reason for the problem. Template instanziation happens at compile
time.
So it cannot handle function parameter of createInstance function at
runtime.
The question is: how shall I realize it differently as follows [pseudo
code]:
if(i == 1)
return C<1>();
if(i == 2)
return C<2>();
// ... maintenance nightmare ...
I'd say it depends on what you are trying to achieve.
#include <iostream>
class Base {
public:
virtual void foo() = 0;
};
template<int T>
class C : public Base {
public:
virtual void foo() { /* default does nothing */ }
};
template<>
class C<1> : public Base {
public:
virtual void foo() { std::cout << "C<1>::foo "; }
};
template<>
class C<2> : public Base {
public:
virtual void foo() { std::cout << "C<2>::foo "; }
};
class Factory {
public:
static Base& createInstance(int i);
};
why a static class member function?
Base& Factory::createInstance(int i) {
// PROBLEM:
// error C2971: 'C' : template parameter 'T' : 'i' : a local variable
cannot be used as
// a non-type argument
// WORKS: int const val = 0;
return C<i>(); //ignore warning: returning address of local variable or
temporary
}
Your factory approach is flawed. You're returning a reference to a
local variable which becomes a dangling reference.
void main() {
Base& anInstance = Factory::createInstance(1);
Base& anotherInstance = Factory::createInstance(2);
}
The function 'main' needs to return an int.
Here the arguments to createInstance are constant expressions. So,
technically you could convert createInstance to a function template.
template<int I>
C<I> createInstance() { return C<I>(); }
int main() {
const Base& b = createInstance<2>();
b.some_virtual_const_function();
}
But what would be the point of it? It looks like you want runtime
polymorphism. Why don't you simply make the int a parameter to the
constructor?
// lib.hh
#include <memory>
class Base {
public:
virtual void foo() = 0;
virtual ~Base() {}
};
std::auto_ptr<Base> factory(int);
// lib.cc
#include <iostream>
#include <ostream>
#include <memory>
class C : public Base {
int myint;
public:
explicit C (int i) : myint(i) {}
~C() {}
void foo();
};
void C::foo() {
std::cout << "C::foo says " << myint << std::endl;
}
std::auto_ptr<Base> factory(int i) {
std::auto_ptr<Base> ap (new C(i));
return ap;
}
// main.cc
#include <memory>
int main() {
std::auto_ptr<Base> apb = factory(2);
apb->foo();
}
Be sure to check out related C++ idioms: handle/body, counted body,
envelope/letter, ...
Cheers!
SG
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]