Dear all
In advance, thank you for your help. I am trying to initialize an object in C++ depending on certain parameter. Below is the source code I am using.

if(ARG::metrn==metrnSMD)
EventStream<complex<Lambda>> evstrTrain(fileTrain, evlsTrain);
else
EventStream<Lambda> evstrTrain(fileTrain, evlsTrain);

if (ARG::FRandomEventOrder())
evstrTrain.SetRandomOrder(true);

I am declaring and calling the constructor for 'evstrTrain' inside the if block, however, in the second if this is not seen and the compiler generates an "undeclared identifier" error, for the part when evstrTrain.SetRandomOrder is called. I need to this quite a few times in my code, can anybody tell me a workaround for this please? I am using Visual Studio C++ 2005.

Regards

Recommended Answers

All 9 Replies

the code in the if-else is equivalent to

if(ARG::metrn==metrnSMD)
{ EventStream<complex<Lambda>> evstrTrain(fileTrain, evlsTrain); }
else
{ EventStream<Lambda> evstrTrain(fileTrain, evlsTrain); }

so the variable is not visible outside the scope of the if or else blocks.

one commonly used work around is to have a polymorphic base class. this works if the method signatures are identical for all the template specializations. eg.

#include <iostream>

struct event_stream_base
{
  virtual ~event_stream_base() {} // this is the destructor; 
   // there is a problem with the daniweb code formatter
  virtual void set_random_order(bool) = 0 ;
} ;

template< typename T > struct event_stream : event_stream_base
{
  explicit event_stream( const T& v ) : member(v) {}
  virtual void set_random_order(bool) 
  { std::cout << member << '\n' ; }
  T member ;
  // ...
};

int main()
{
  int a = 8 ;
  event_stream_base* pesb = 0 ;
  if( a > 5 ) pesb =  new event_stream<double>(2.34) ;
  else pesb =  new event_stream<int>(73) ;

  pesb->set_random_order(true) ;

  delete pesb ;
}

(another is to use a meta-function; but it may be prudent to ignore this option for now.)

I think the original problem (causing the compiler error) is this: EventStream<complex<Lambda[B]>>[/B] evstrTrain( ... C++ compilers can't distinguish this from the right-shift operator. You need to have a space between them: EventStream<complex<Lambda[B]> >[/B] evstrTrain( ... Hope this helps.

commented: good catch +13

> I think the original problem (causing the compiler error) is this:
> EventStream<complex<Lambda>> evstrTrain( ...
he is using Visual Studio C++ 2005. which accepts this (perhaps in anticipation of c++0x).

> I think the original problem (causing the compiler error) is this:
> EventStream<complex<Lambda>> evstrTrain( ...
he is using Visual Studio C++ 2005. which accepts this (perhaps in anticipation of c++0x).

Dear vijayan121

Thank you for your fast answer and your time. I saw your solution but I think is not viable. I am currently modifying a HUGE software project and trying to make a base class that emulates "eventstream" is not feasible.

Is there any other workaround?. Actually I am sort of surprised, what I intend is so simple, if (ARG::metrn) has some value declare EventStream evntstrTrain calling with the complex template, else declare it with the Lambda template.

I have been surfing the web last 2 hours but have not seen any workaround. Again, your help is appreciated.

To Douas, Thank you very much for the answer, but it is not a problem of syntax. The problem is of the scope of the variables, if I declare them inside an if block, the scope is local only to that if block, and I want them to be local to the whole function.

Thanks again.

Regards

well, for the simple example you posted, you could write

if(ARG::metrn==metrnSMD)
{
     EventStream<complex<Lambda>> evstrTrain(fileTrain, evlsTrain);
     if (ARG::FRandomEventOrder()) evstrTrain.SetRandomOrder(true);
}
else
{
     EventStream<Lambda> evstrTrain(fileTrain, evlsTrain);
     if (ARG::FRandomEventOrder()) evstrTrain.SetRandomOrder(true);
}

but this may not be pragmatic in more complex cases (where the second if is not proximate to the first if-else)

well, for the simple example you posted, you could write

if(ARG::metrn==metrnSMD)
{
     EventStream<complex<Lambda>> evstrTrain(fileTrain, evlsTrain);
     if (ARG::FRandomEventOrder()) evstrTrain.SetRandomOrder(true);
}
else
{
     EventStream<Lambda> evstrTrain(fileTrain, evlsTrain);
     if (ARG::FRandomEventOrder()) evstrTrain.SetRandomOrder(true);
}

but this may not be pragmatic in more complex cases (where the second if is not proximate to the first if-else)

Dear vijayan121
Again thanks for your fast answer.

As you said, this is not pragmatic in more complex cases. The problem is that I have more parts when I should do parameter dependent variable declaration, and in those cases this "super if" solution is also not feasible. Thank you again for your invaluable insights. Do you have any other idea?, this is for a very important job and the deadline is really soon. Sorry for any inconveniences.

Regards

> what I intend is so simple, if (ARG::metrn) has some value declare EventStream evntstrTrain
> calling with the complex template, else declare it with the Lambda template.

if there are only a limited number of possibilities (like two in the example), you could use a variable of type boost::any http://www.boost.org/doc/html/any.html to hold the variable and do a type check later to figure out what it is.

#include <iostream>
#include <boost/any.hpp>
#include <typeinfo>

template< typename T > struct event_stream
{
  explicit event_stream( const T& v ) : member(v) {}
  void set_random_order(bool) { std::cout << member << '\n' ; }
  T member ;
  // ...
};

int main()
{
  int a = 8 ;
  boost::any any ;
  if( a > 5 ) any = event_stream<double>(2.34) ;
  else any = event_stream<int>(73) ;

  // ...

  if( any.type() == typeid( event_stream<double> ) )
    boost::any_cast< event_stream<double> >(
           any).set_random_order(true) ;
  else if( any.type() == typeid( event_stream<int> ) )
    boost::any_cast< event_stream<int> >(
           any).set_random_order(true) ;
}

Nice! Boost rocks!

Sorry I wasn't paying attention when I responded earlier...

Dear vijayan121 and Duoas
Thank you very much for your interest. I am relatively new to C++. Though I have experience in C and other languages, I can fairly manage myself up to intermediate level programming. This advanced part on templates and other subtleties of C++ are new to me.

I haven't tried the boost solution since I will have to pass that variable to another function, and if it is wrapped into the 'any' variable I will have to modifiy everything. Due to my inexperience with C++, never thought it would turn out so extremely complex something I thought it was 'simple'. Also, this is a run once and forget software, so as long as it runs once or twice will be OK.

I will use the "super if" solution, since I am almost out of time.

Again, thank you very much for your kind time and explanations, deeply appreciate them.

Best regards

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.