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! ]