Declaration inside if/switch - c++

I'm trying to do something like this in C++:
if(){
int a;
} else if(){
char a;
} else {
double a;
}
f(a);
But I get an error from the compiler saying that a was not declared in this scope.
I need to do a conditional declaration, how can I do it?
Many thanks
edit:
I cannot move the function inside the conditional as the problem is bigger:
f(a,b,c);
where a, b and c need to be declared in this way.

One way of doing what you seem to want is by defining a template function. You define the template and the compiler will compile versions of the function for each type you call it with.
template <typename T_my_type> T_my_type MyTemplateFunction(T_my_type a)
{
a++;
std::cout << a;
return a;
}
if(){
int a;
MyTemplateFunction(a);
} else if(){
char a;
MyTemplateFunction(a);
} else {
double a;
MyTemplateFunction(a);
}
In this case T_my_type is the template parameter and will be implicitly replaced with the type of the parameter that you call the function with.
Template programming in C++ is a rather large can of worms to open though, and as others have suggested, I think you may need to rethink your approach.

It appears that you want different overloads to be called depending on the path taken through the conditional structure. This is not possible in a static language like C++ because the compiler needs to decide which overload to call at compile time, and can only pick one for each call.
Do this instead:
if (...) {
int a = ...;
f(a);
} else if (...) {
char a = ...;
f(a);
} else {
double a = ...;
f(a);
}

C++ is a statically typed language. If you want to deal with a variable its type must be known at compile-time. If the conditions you want to check for are also known at compile-time there's probably a nice solution involving templates. If the expressions in your if statements are runtime dependent you have to move the function call inside the blocks that declare a.

you could use a union.
union my_type
{
int i;
char c;
double d;
}
my_type a;
if(){
a.i = ...;
} else if(){
a.c = ...;
} else {
a.d = ...;
}
f(a);
I don't know what f() will be doing, so I don't know if this will work in your situation. As someone else stated, templates are one option. Or you could try just type-casting instead of using a union.

Consider this instead:
union T
{
int i;
double d;
char c;
}
void process()
{
T t;
if(....) { work with t.i }
else if(....) { work with t.d }
else if(....) { work with t.c }
f(t);
}
void f(T t)
{
// now you have all your possible answers inside one variable
// you might need to send a 2nd flag to mark the actual type inside
// depending on your problem however, you might not need it
// work with t.i, t.d or t.c
}

If you must have f() on the outside and don't want to use unions, you can consider polymorphism:
class Base {};
class AInt : public Base { int a; };
class AChar : public Base { char a; };
class ADouble : public Base { double a; };
Base *p = NULL;
if(){
p = new AInt();
} else if(){
p = new AChar();
} else {
p = new ADouble();
}
f(a, b, c);
Ofcourse for this to have any real OOP quality you'll have to add some virtual methods to the Base class and implement them in the inheriting class to do the actual work you need be done or else you'll have this switch again somewhere inside f(), probing the real type of a.

You can also make f() as template function and implement the function for different data types.
f(template class T)
{
}

you can use boost library. For example
1. Boost::Any
boost::any a;
a=std::string("A string");
a=42;
a=3.1415;
f(a);
Link http://www.boost.org/doc/libs/1_40_0/doc/html/any.html
Boost::Variant
boost::variant a;
a=24;
a=2.52;
a="Fabulous!";
a=0;
f(a);
Link http://www.boost.org/doc/libs/1_40_0/doc/html/variant.html

If it possible, define macros for your conditions. In that way you can use this syntax
#if defined(CONDITION1)
int a;
f(a);
#elif defined(CONDITION2)
char a;
f(a);
#elif defined(CONDITION3)
double a;
f(a);
#endif

This is possible with a void pointer taking function. You would simply have to create a as a void* then have it point to one of your chosen variables. Then your function can simply handle which type it is. For example:
void *a;
int b;
char c;
double d;
char typeofa;
if(foo == 1){
a = &b;
typeofa = 0;
} else if(foo == 2){
a = &c;
typeofa = 1;
} else {
a = &d
typeofa = 2;
}
int bar(void* a, char typeofa)
{
//etc, do right thing dependant on typeofa
//casting a to right type then dereferencing
}
Note, I have not tested this code so it may contain minor syntax errors but demonstrates the principal.

Related

template deduction/substitution fails on smart pointers

Let's consider this code:
template<typename T>
struct A
{
//...
};
struct B : public A<int>
{
//...
};
template<typename T>
bool validate(A<T>* p)
{
//...
return true;
};
int main()
{
A<int>* pA;
std::cout << validate(pA) << std::endl;
B* pB;
std::cout << validate(pB) << std::endl;
}
It compiles correctly and works as expected. Now, let's say I'd need to refactor the code to use smart pointers instead, then also validate could be changed like this:
template<typename T>
bool validate(std::shared_ptr<A<T>> p)
{
//...
return true;
};
int main()
{
std::shared_ptr<A<int>> pA = std::make_shared<A<int>>();
validate(pA); //it compiles correctly
std::shared_ptr<B> pB = std::make_shared<B>();
validate(pB); //it FAILS to compile
}
You can verify that here.
What is the reason behind this?
What is the best way to solve this problem without modifying A or B?
This is because it requires to perform custom casting from shared_ptr<B> to shared_ptr<A<int>> to disambiguate the template function parameters. Disambiguation of template functions parameters doesn't even attempt to do type casting (aside from some basic stuff).
It is simply not practictical to even try. Well, theoretically there could've been a partial solution that specify which custom castings to try but there isn't. Just use SFINEA and disambiguate it yourself instead of asking compiler to do it for you.
In general you should avoid smart pointers if the called function does not change ownership! Use your raw pointer function.
You force a Generic type of A in function validate. Inheritance is not considered here.
If you ignore inheritance it could look like:
template<typename T>
bool validate(std::shared_ptr<T> p)
{
return true;
}
See on Godbolt
To force a base class I would introduce a Typetag.
The ways around this I can see possible are:
Alternative 1)
std::shared_ptr<B> pB = std::make_shared<B>();
//... do your type B related operations through pB
validate(std::shared_ptr<A<int>>(pB));
Alternative 2)
template<typename T>
bool validate(A<T> const & a)
{
//...
return true;
}
int main()
{
std::shared_ptr<A<int>> pA = std::make_shared<A<int>>();
validate(*pA);
std::shared_ptr<B> pB = std::make_shared<B>();
validate(*pB);
}
Alternative 3)
template<typename T>
bool validate(std::shared_ptr<A<T>> p)
{
//...
return true;
}
template<typename T>
bool validate(std::shared_ptr<T> p)
{
//...
return true;
}
int main()
{
std::shared_ptr<A<int>> pA = std::make_shared<A<int>>();
validate(pA); // it uses bool validate(std::shared_ptr<A<T>> p)
std::shared_ptr<B> pB = std::make_shared<B>();
validate(pB); // it uses bool validate(std::shared_ptr<T> p)
}
but that implies that the function might extend to many other types, and it is not necessarily a desired behaviour (maybe?).
Any other suggestions guys?
It would be cool if someone knows why the code in the question doesn't work in the first place.

Returning anonymous struct

It seems you can return an unnamed struct this way:
auto foo() {
struct {
int bar;
int square() {
return bar * bar;
}
} a { 7 };
return a;
}
Is there anyway to do this without the redundant variable name a, thus anonymously?
For starters C++ does not define anonymous structures. I think you mean an unnamed structure.
According ro the C++ Standard the return statement is defined like (8.6 Jump statements)
return expr-or-braced-init-listopt ;
So you may not use a declaration in the return statement. If so then you need prelimary to declare an object of the structure type that will be returned.
I have no idea what the point of this exercise is, so here is an answer that technically does what you ask for:
auto helper()
{
struct {
int x;
} a {0};
return a;
}
decltype(helper()) foo()
{
return {8};
}
https://godbolt.org/z/zA8C1V
The struct is unnamed.
foo does not return a named variable.
Of course this is straight up ridiculous - one would just name the struct instead of this decltype tomfoolery.
No, this is not possible.
The closest you can get is to use a functional-style cast to create a temporary, and use a C99-style scoped-initialiser; GCC allows this in C++ mode, as an extension:
#include <iostream>
#include <string>
auto foo() {
return (struct {
int bar;
int square() {
return bar * bar;
}
}) { 7 };
}
… but this is not portable (and will warn).
Without the braces around 7 the extension is not triggered, and you're back to standard code, in which it is illegal to define a type in a cast.
Instead of writing obtuse code, give your type a name and give your object a name. Your readers will thank you.
None of
struct {/*...*/} foo() { // Illegal
return {/*...*/};
}
auto foo() {
return struct { /*...*/ } { /*...*/ }; // Illegal
}
template <typename T = struct { /*...*/ }> // Illegal
T foo() {
return { /*...*/ };
}
are legal.
You have to, at least, have a named type, or a named instance.
Lambda allows to have neither, but you can only capture and define its operator():
auto foo() {
return [/*...*/](/*...*/) { /*...*/ }; // Legal
}
Returning anonymous struct
There is no such thing as anonymous struct in C++. That's enough to make it impossible.
There is a - limited - way of returning an object of anonymous type from a function: Returning a lambda.
auto make_square_function() {
return [bar = 7]() {
return bar * bar;
};
}
Lambdas are much more limited than general classes though. The members (captures) are encapsulated and cannot be named from the outside of the lambda and there are no member functions other than the function call overload.
Is there anyway to do this without the redundant variable name a
Only if you give the class a name:
struct Squarer {
int bar;
int square() {
return bar * bar;
}
};
auto foo() {
return Squarer{7};
}
Returning an instance of unnamed class is only possible by defining a variable.
Just for fun, another define-the-variable-in-another-function solution (taking inspiration from Max Langhof's answer)
auto foo ()
{
return []{ struct{int bar;} a {7}; return a; }();
}
No, because you need to return an instance of an object, in this case a.
The returned object has to exist somewhere in memory, you can't just return a class definition.
In your example, you don't return an anonymous struct, but you return an instance of that struct.

automatic calling custom converter of raw pointers A* <-> B*

Is it possible to define a custom converter (converter1<T> and converter2) between different types of raw pointer A* and B*,
then make all functions (fa() and fb()) in a certain class
use an appropriate converter (converter1<T> or converter2)?
In short, I want the program to convert A* to B* and vice versa USING my custom functions.
I wish it would do that automatically for my convenience.
class Manager{
void fb(B* b){ /** something complex */ }
void fa(A* a){ /** different thing complex */ }
void testCase(){
A* a= ... ;
fa(a);
fb(a); //automatic convert to B* using "converter2" (wish)
B* b= ... ;
fa(b); //automatic convert to A* using "converter1" (wish)
fb(b);
}
template<class T> T* converter1(B* b){ //hardcoded, non-static.
return this->getId<T>(b);
//^^^ just an example to show how custom it is,
// currently T=A
}
B* converter2(A* a){ //hardcoded
return a->getB();
//^^^ just an example to show how custom it is.
}
}
The real case has many A - A1, A2, A3 and so on.
A and B are not derived from each other.
I wish there is a way. I think about constructor of pointer.
No this is not possible.
Pointers are built-in types and only built-in conversions between built-in types exist. User-defined conversions only work for user-defined class types.
You may want to switch to your own brand of smart pointers to handle this.
through references (or smart pointers) it's more possible:
struct A {};
struct B {};
A& convert_to_a(A& a) { return a; }
A convert_to_a(B const& b) {
// makes a new A from a B
return A();
}
B& convert_to_b(B& b) { return b; }
B convert_to_b(A const& a) { return B(); }
struct Manager
{
template<class T>
void fa(T&& t) {
auto&& a = convert_to_a(t);
// do something with a
(void)a;
}
template<class T>
void fb(T&& t) {
auto&& b = convert_to_b(t);
// do something with b
(void)b;
}
};
int main()
{
A a;
B b;
Manager m;
m.fa(a);
m.fb(a);
m.fa(b);
m.fb(b);
}
It is not possible the way you want it.
Anyway, you can use a catch-all function and a bunch of traits to simulate it.
It follows a minimal, working example:
#include<iostream>
struct A {};
struct B {};
template<typename T>
A* ToAConverter(T*) = delete;
template<>
A* ToAConverter<B>(B *b) {
// just an example
return new A;
}
struct Manager{
void fa(A* a){ std::cout << "fa" << std::endl; }
template<typename T>
void fa(T *t) {
std::cout << "convert and forward" << std::endl;
fa(ToAConverter<T>(t));
}
void testCase(){
A *a = new A;
fa(a);
B *b = new B;
fa(b);
}
};
int main() {
Manager m;
m.testCase();
}
In case you haven't defined a converter for a specific type, you'll receive a compile-time error.
As you can see, you have no longer to call explicitly the converter when you invoke fa.

Dynamically create a function pointer that calls a method on a given instance

I suspect this is impossible, but thought I'd ask. Say I have a class with a method:
class A {
public:
void b(int c);
};
I can make a pointer to that member function:
void (A::*ptr)(int) = &A::b;
(someAInstance.*ptr)(123);
I can also abuse function pointers and make a pointer that takes the A argument directly (I don't know if this is safe, but it works on my machine):
void (*ptr2)(A*, int) = (void (*)(A*, int))&A::b;
(*ptr2)(&someAInstance, 123);
What I want is to somehow curry the A argument, and create a function pointer that just takes an int, but calls the A::b method on a particular A instance I've predefined. The A instance will stay constant for that particular function pointer, but there may be several function pointers all pointing to the same A::b method, but using different A instances. For example, I could make a separate wrapper function:
A* someConstantA = new A;
void wrapper(int c) {
someConstantA->b(c);
}
void (*ptr3)(int) = &wrapper;
Now I can use ptr3 without knowing which particular A it's dispatching the call to, but I had to define a special function to handle it. I need a way to make pointers for any number of A instances, so I can't hardcode it like that. Is this in any way possible?
Edit: Should've mentioned, I'm trapped in C++03 land, and also can't use Boost
Don't create a wrapper function, create a wrapper functor. This allows you to encapsulate whatever state you want to (e.g. an A*) in a callable object.
class A {
public:
void b(int c) {}
};
struct wrapper {
A* pA;
void (A::*pF)(int);
void operator()(int c) { (pA->*pF)(c); }
wrapper(A* pA, void(A::*pF)(int)) : pA(pA), pF(pF) {}
};
int main () {
A a1;
A a2;
wrapper w1(&a1, &A::b);
wrapper w2(&a2, &A::b);
w1(3);
w2(7);
}
If you have a sufficiently new compiler (e.g. gcc 4.2+), it should include TR1, where you could use std::tr1::bind:
#include <cstdio>
#include <tr1/functional>
class A {
public:
void b(int c) {
printf("%p, %d\n", (void*)this, c);
}
};
int main() {
A* a = new A;
std::tr1::function<void(int)> f =
std::tr1::bind(&A::b, a, std::tr1::placeholders::_1); // <--
f(4);
delete a;
return 0;
}
It is also doable in pure C++03 without TR1, but also much more messier:
std::binder1st<std::mem_fun1_t<void, A, int> > f =
std::bind1st(std::mem_fun(&A::b), a);
You could also write your own function objects.
Note that, in all the above cases, you need to be very careful about the lifetime of a since that is a bare pointer. With std::tr1::bind, you could at least wrap the pointer in a std::tr1::shared_ptr, so that it can live just as long as the function object.
std::tr1::shared_ptr<A> a (new A);
std::tr1::function<void(int)> f =
std::tr1::bind(&A::b, a, std::tr1::placeholders::_1);
If you are using C++11, you might use a lambda (untested code):
template<typename T, typename A>
std::function<void(A)> curry(T& object, void (T::*ptr)(A))
{
return [](A a) { (object.*ptr)(std::forward<A>(a)); }
}
I'd be using Boost::bind for this.
Basically:
class A
{
int myMethod(int x)
{
return x*x;
}
};
int main(int argc, char* argv[])
{
A test();
auto callable = boost::bind(&A::myMethod, &A, _1);
// These two lines are equivalent:
cout << "object with 5 is: " << test.myMethod(5) << endl;
cout << "callable with 5 is: " << callable(5) << endl;
return 0;
}
I think that should work. I'm also using auto in here to deduce the type returned by boost::bind() at compile-time, which your compiler may or may not support. See this other question at stackoverflow for an explanation of the return type of bind.
Boost supports back to Visual Studio 2003 (I think) and this all this will work there, though you'll be using BOOST_AUTO I think. See the other question already linked for an explanation.
What you want to do is not possible.
To see why, assume that it is possible - the function pointer must point to a function somewhere in your executable or one of its libraries, so it must point to a function that knows which instance of A to call, much like your wrapper function. Because the instance of A is not known until runtime, you'd have to create those functions at runtime, which isn't possible.
What you're trying to do is possible in C++03, as long as you're happy to pass around a function object rather than a function pointer.
As others have already given solutions with C++11 lambdas, TR1 and boost (all of which are prettier than the below), but you mentioned you can't use C++11, I'll contribute one in pure C++03:
int main()
{
void (A::*ptr)(int) = &A::b;
A someAInstance;
std::binder1st<std::mem_fun1_t<void,A,int> > fnObj =
std::bind1st(std::mem_fun(ptr), &someAInstance);
fnObj(321);
};
I've worked something out with a template Delegate class.
// T is class, R is type of return value, P is type of function parameter
template <class T, class R, class P> class Delegate
{
typedef R (T::*DelegateFn)(P);
private:
DelegateFn func;
public:
Delegate(DelegateFn func)
{
this->func = func;
}
R Invoke(T * object, P v)
{
return ((object)->*(func))(v);
}
};
class A {
private:
int factor;
public:
A(int f) { factor = f; }
int B(int v) { return v * factor; }
};
int _tmain(int argc, _TCHAR* argv[])
{
A * a1 = new A(2);
A * a2 = new A(3);
Delegate<A, int, int> mydelegate(&A::B);
// Invoke a1->B
printf("Result: %d\n", mydelegate.Invoke(a1, 555));
// Invoke a2->B
printf("Result: %d\n", mydelegate.Invoke(a2, 555));
_getch();
delete a1;
delete a2;
return 0;
}

Can you evaluate a constructor call to boolean with an overloaded bool()?

Can a constructor call be evaluated to a boolean if the bool() operator is overloaded?
class A
{
public:
A() {};
operator bool() const { return true; }
}
main()
{
if (A a = A())
{
// do stuff
}
}
Is the above code valid, or do I need to implement main like:
int main(int argc, const char* argv[])
{
A a();
if (a)
{
// do stuff
}
}
This code is going to wind up all over the place in my code base, so less lines, increased legibility, and reduced scope are important, and would be improved by this.
Any ideas?
The code contains a few syntactic and semantic bugs. Let's fix them
class A
{
public:
A() {};
operator bool() { return true; }
};
int main()
{
if (A a = A())
{
// do stuff
}
}
You may choose to change the type in the conversion function to something else. As written, the boolean conversion will also succeed to convert to any integer type. Converting to void* will limit conversion to only bool and void*, which is a commonly used idiom. Yet another and better way is to convert to some private type, called safe bool idiom.
class A
{
private:
struct safe_bool { int true_; };
typedef int safe_bool::*safe_type;
public:
A() {};
operator safe_type() { return &safe_bool::true_; }
};
Back to syntax: If you have an else part, you may use the name of the declared variable, because it's still in scope. It's destroyed after all branches are processed successfully
if(A a = A())
{ ... }
else if(B b = a)
{ ... }
You may also use the same name as before, and the variable will shadow the other variables, but you may not declare the same name in the most outer block of any branch - it will conflict rather than hide with the other declaration.
if(int test = 0)
{ ... }
else
{ int test = 1; /* error! */ }
The technique to declare and initialize a variable is most often used together with dynamic_cast though, but can be perfectly used together with a user defined type like above, too
if(Derived *derived = dynamic_cast<Derived*>(base)) {
// do stuff
}
Note that syntactically, you have to initialize the variable (using the = expression form like for a default argument). The following is not valid
if(ifstream ifs("file.txt")) {
// invalid. Syntactic error
}
The answer to your first question is "yes", but your "constructor call" is wrong. A a declares a variable. It's a statement, not an expression. A() is an expression which constructs an anonymous temporary instance of A:
struct A
{
A() {};
operator bool() { return true; }
};
int main()
{
if (A())
{
// do stuff
}
}
If you want to use the instance of A in "stuff", then you need:
if (A a = A()) {
// do stuff
}
You can do this, but only when you're using the copy-initialization syntax to call your constructor. For example:
main()
{
if (A a = A())
{
// do stuff
}
}
Most compilers would elide the copy constructor in such an initializer when optimizations are enabled, but an accessible constructor is required nonetheless.
Also, naturally, if A would have a constructor such as A(int), you could also do this:
if (A a = 123) ...
Also, it is generally considered a bad idea to have operator bool() on your class for such purposes. The reason is that bool is in turn implicitly convertible to any numeric type (with false == 0 && true == 1); so, for example, the client of your class can write:
int x = A();
void foo(float y);
foo(A());
which is probably not something you want to allow. A simple trick is to use a pointer-to-member-of-private-class instead:
class A {
private:
struct dummy_t { int dummy; };
typedef int dummy_t::*unspecified_boolean_type;
public:
operator unspecified_boolean_type() const {
if (...) {
return &dummy_t::dummy; // true
} else {
return 0; // false
}
}
};
Pointers-to-members have an implicit bool conversion (as usual, null pointer is false, anything else is true), but they are not compatible with any type but their own; and, since the inner class here is private, no client code can possibly declare a variable of that type (auto and decltype in C++0x provide a way, though).
As a side note, main() as written is not valid C++ - ISO C++ does not have "default int" rule the way C does, and a function without an explicit return type is invalid.
If you're trying to indicate failure, why not throw an exception?
#include <stdexcept>
class Foo
{
public:
Foo(void)
{
if (/* something bad D: */)
{
throw std::runtime_error("Couldn't open file, etc...");
}
}
}
int main(void)
{
try
{
Foo f;
// do stuff with f
}
catch (std::exception& e)
{
std::cerr << "Error: " << e.what() << std::endl;
}
}