Using vs typedef in class - c++

I thought the new using syntax in C++11 and typedef were equivalent (except for templates). But it seems that with using it is also not possible to declare a class member.
class A {
//... Public members
private:
typedef std::vector<double> vector_double;
using vector_int = std::vector<int>;
void bar(vector_double& vecDouble); // type can be used
void foo(vector_int& vecInt); // type can't be used: synatx error
// ... Possible other private members
}
When I try to use the type vector_int in one of the member functions of class A I get a compiler error: syntax error: identifier 'vector_int'.
Am I doing something wrong here or is defining a member type not possible with using?

Related

Overwriting existing type with typedef inside a class

I want to overwrite a type with a typedef. The rationale for doing this is that one of my class has lot of templates and i want to replace all calls to that class with the templatized class (so that within another class Achild means Achild<T>. However, i get an error.
template <typename T>
class Achild
{
public:
Achild<T>() = default;
};
class Foo
{
typedef Achild<int> Achild;
public:
Foo() = default;
};
int main()
{
auto foo = new Foo();
}
I get the following error:
new_test.cpp:12:22: error: declaration of ‘typedef class Achild<int> Foo::Achild’ [-fpermissive]
typedef Achild<int> Achild;
^~~~~~
new_test.cpp:2:10: error: changes meaning of ‘Achild’ from ‘class Achild<int>’ [-fpermissive]
class Achild
How can i get this to work? The example is only for sample and my reasons for doing this is also related to how i have to get this to work with an existing codebase.
You are aliasing the type with itself (Achild already a type since you declared it in your class). You should instead do:
using Child = Achild<int>;
Note that you also should use the keyword using instead of typedef since it is the equivalent (and more robust) in C++. See What is the difference between 'typedef' and 'using' in C++11?.

error: ISO C++ forbids declaration of '' with no type

I got error: ISO C++ forbids declaration of 'InvalidSig' with no type of the below header file, how to solve it?
struct args{
InvalidSig* context; //error
string mname;
};
class InvalidSig{
.......
}
You can forward declare class InvalidSig above:
class InvalidSig;
struct args {
InvalidSig* context;
// ...
};
You can also do this, if you only want to use the name once before its definition:
struct args {
class InvalidSig* context;
// ...
};
I recommend avoiding the latter though, as the former is more common and will be less confusing to anyone reading your code.

Why am I getting this 'enum' is not a class or a namespace error?

I need call a method with this signature in my Manager class:
void createPlayer(Player& player, PlayerType& playerType);
I have a Player defined like so:
using namespace std;
enum PlayerType { FORWARD, DEFENSEMAN, GOALIE };
class Player {
public:
Player();
void setType(PlayerType);
private:
PlayerType type;
};
This is how I try to call the method in main ...
#include "Player.h"
#include "Manager.h"
int main() {
Manager manager;
Player player;
PlayerType t = PlayerType::FORWARD;
manager.createPlayer(player, t);
return 0;
}
... but it fails to compile with this error:
Main.cc: In function ‘int main()’:
Main.cc:12:18: error: ‘PlayerType’ is not a class or namespace
Any ideas? Note: I cannot change the signature of the createPlayer method.
enum doesn´t create a namespace.
Therefor PlayerType t = PlayerType::FORWARD; should be changed to:
PlayerType t = FORWARD;
Notice that c++11 introduce enum classes, which have a namespace. Beside this MSVC has an extension which treats (regular) enums like they have namespace. So your code should actually work with MSVC.
Unfortunately enum by default doesn't create an enum namespace. So when declaring:
enum PlayerType { FORWARD, DEFENSEMAN, GOALIE };
you'll have to use it like this:
auto x = FORWARD;
Thankfully, though, C++11 introduced enum class or enum struct to solve this issue:
enum class PlayerType { FORWARD, DEFENSEMAN, GOALIE };
You'll then be able to access it like you did:
auto x = PlayerType::FORWARD;
Your error seems to be in this line:
PlayerType t = PlayerType::FORWARD;
As far as I know, the scope resolution operator (::) is not valid on regular C++98 enums unless your compiler supports them through non-standard extensions (like Visual Studio). Therefore you can't use it to reference an specific value from the enumerator.
Also, C++98 enums have the problem of polluting the namespace in which they are defined which can lead to name clash. Luckily C++11 solved this introducing the enum class. For more information check Stroustrup's FAQ: http://www.stroustrup.com/C++11FAQ.html#enum
add a static function say getForward:
class Player {
public:
Player();
void setType(PlayerType);
static PlayerType getForward {
return FORWARD;
}
private:
PlayerType type;
};
Then use it in main:
manager.createPlayer(player, Player::getForward());
This should work.

pointer to member function inside namespace

I've got a namespace MyNamespace containing a class MyClass with many static public members functions.
What I need to do, is to build, inside the namespace, a map containing a pointer on every public members functions of the class
Here the code:
#include <iostream>
#include <map>
namespace MyNamespace {
class MyClass;
typedef bool (*fctPtr)(void);
typedef std::map<std::string, fctPtr> fctMap;
};
class MyNamespace::MyClass {
public:
static bool func1(void) { return true; };
static bool func2(void) { return true; };
static bool func3(void) { return true; };
static bool func4(void) { return true; };
};
MyNamespace::fctMap MyFctMap;
void execFct() {
MyNamespace::MyClass obj;
MyNamespace::fctPtr fctMemb;
fctMemb = MyFctMap["func1"];
(obj.*fctMemb)();
}
int main() {
MyFctMap["func1"] = &MyNamespace::MyClass::func1;
MyFctMap["func2"] = &MyNamespace::MyClass::func2;
MyFctMap["func3"] = &MyNamespace::MyClass::func3;
MyFctMap["func4"] = &MyNamespace::MyClass::func4;
execFct();
}
And what the compiler says:
% clang++ draft.cc
draft.cc:29:7: error: right hand operand to .* has non pointer-to-member type
'MyNamespace::fctPtr' (aka 'bool (*)()')
(obj.*fctMemb)();
^ ~~~~~~~
1 error generated.
I don't understand why I got this error neither what to do to resolve the problem. Idea?
Edit: I'm using c++98 and no boost.
Working with a typedef bool (MyClass::*fctPtr)(void) drives me to this kind od error, at map assignment time.
error: assigning to 'mapped_type' (aka 'bool (MyNamespace::MyClass::*)()') from
incompatible type 'bool (*)()'
MyFctMap["func1"] = &MyNamespace::MyClass::func1;
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Since the functions you are referencing are static, you don't need the obj class reference. Simply call fctMemb();. You might also consider if you need these functions mapped in such a way, oftentimes you don't need that dynamic aspect to function references in C++ and instead should be using templates.
A pointer to a function is not the same as a pointer to a member function. The important thing to remember is that all (non-static) member function actually have a hidden first argument which is what becomes the this pointer. Therefore a function pointer and a member function pointer can't ever be compatible.
However, you should look into std::function and std::bind:
namespace NyNamespace
{
typedef std::function<bool()> fctPtr;
...
}
MyNamespace::MyClass myObject;
MyFctMap["func1"] = std::bind(&MyNamespace::MyClass::func1, myObject);
The idea is fctMemb(); :-)
fctPtr, as the compiler says, is not a pointer to member type...
Static member functions are not like normal member functions. They have access to class private and protected members, but they are not tied to object instances and thus can't access this pointer nor any non-static members.
Their type is that of normal function pointers and they can't be bound to member function pointers (and normal function pointers is what you have in your code).
You call them like normal functions:
fctMemb();
Btw, the sytax to form member function pointers is different:
struct Foo {
void f() {}
};
void (Foo::* mem_fun_ptr)() = &Foo::f;

typedef function pointer that takes argument ClassName* before defining ClassName?

I have the following situation:
typedef void (*F_POINTER)(ClassName*);
class ClassName {
public:
F_POINTER f;
}
This happens because an instance of ClassName needs to pass a pointer itself to the client. However, If I write things in this order, I get complains about ClassName not declared, whatnot. However, if I switch them around, I get complains about F_POINTER not being declared when I declare the instance in the class.
So maybe I'm missing something simple here, but how would I accomplish this?
Forward declaration:
class ClassName;
typedef (*F_POINTER)(ClassName*);
class ClassName {
public:
F_POINTER f;
}
Or shorter:
typedef (*F_POINTER)(class ClassName*); // implicit declaration;
This seems to be working under GCC 4.5.2 (mingw32):
typedef void (*F_POINTER)(class ClassName);
class ClassName {};
void f (ClassName) {}
int main ()
{
F_POINTER x = f;
}
I wouldn't trust my life on whether it is legal C++ or not, not even the pointer version described by other people. Forward declarations and pointers do not solve everything, for example it is not possible to declare methods that throw pointers of incomplete types, you need full definition for that. This might be similarly illegal, just accepted by compilers.
Forward declare ClassName. The type can be incomplete to use a pointer to it.
class ClassName;
typedef (*F_POINTER)(ClassName*);
class ClassName { ... };
Alternatively, move the typedef inside the class. Also consider using boost::function/std::function instead of function pointers.
Either you can forward declare it as,
class ClassName;
typedef void (*F_POINTER)(ClassName*); // assume that return is `void`
before the F_POINTER or you can use the template trick to avoid such hassels for every class:
template<typename RETURN, typename ARGUMENT>
struct FuncPtr { typedef RETURN (*F_POINTER)(ARGUMENT); };
Usage:
class ClassName {
public:
FuncPtr<void,ClassName*>::F_POINTER f;
};