Why can I compile the following:
typedef void OnSuccessSignature(PathFinderType::EdgePath);
but not this?:
using OnSuccessSignature = void(PathFinderType::EdgePath);
The second line gives a C2061: syntax error : identifier 'EdgePath'
In case it makes a difference, the relevant part of the class is defined as
class MapManager : public Service<MapManager>
{
public:
// Aliases.
using PathFinderType = AStar<Map::MapNodeType, WeightedEuclideanDistance<Map::MapNodeType>>;
using OnSuccessSignature = void(PathFinderType::EdgePath);
// ...
}
and AStar
template <typename TNode, typename THeuristic = EuclideanDistanceSqrd<TNode>>
class AStar : Detail::AStarHeap<TNode>
{
public:
// Aliases.
using EdgePath = list<typename TNode::EdgeType*>;
// ...
}
I've included the second header in the first.
Related
all!
I want write a template structure, which will give me concrete name of a class based on enum. In details:
in .h file
#include "Mish.h"
#include "ReLU.h"
namespace a
{
namespace b
{
enum class ActivationEnum : size_t
{
Mish,
ReLU
};
template <ActivationEnum act>
struct Activation
{
};
template <>
struct Activation<ActivationEnum::Mish>
{
using aType = Mish;
};
template <>
struct Activation<ActivationEnum::ReLU>
{
using aType = ReLU;
};
} // raul namespace
}
Then I want to use it in code as:
void someF(..., ActivationEnum act)
{
...
OtherClass<Activation<act>::aType> bla;
...
}
I've faced with two problems:
Mish and ReLU are implemented in Mish.cpp and ReLU.cpp files in namespace a, includes are here, but I got errors syntax error: identifier 'ReLU' and syntax error: identifier 'Mish'. If I add forward declaration here such as namespace a { class Mish; class ReLU; ... } then everything is ok here.
No matter in function someF I receive invalid template argument for 'a::b::Activation', expected compile-time constant expression
What are the problems? How can I return different typenames based on enum? Thank you.
I have a header class that looks like this:
#ifndef A_H__
#define A_H__
using namespace pcl::tracking;
namespace ball_tracking_cloud
{
template <typename PointType>
class OpenNISegmentTracking
{
public:
//...
protected:
void update(const sensor_msgs::PointCloud2ConstPtr &input_cloud);
}; // end of class
} // end namespace
#endif
And now I have a .cpp file that looks like this:
#include <ball_tracking_cloud/particle_detector.h>
bool init = true;
namespace ball_tracking_cloud
{
void OpenNISegmentTracking<pcl::PointXYZRGBA>::update(const sensor_msgs::PointCloud2ConstPtr &input_cloud)
{
pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGBA>);
pcl::fromROSMsg(*input_cloud, *cloud);
if(init)
{
v.run ();
init=false;
}
v.cloud_cb(cloud);
}
} // end of namespace
If I compile my code I get this error:
: error: specializing member ‘ball_tracking_cloud::OpenNISegmentTracking<pcl::PointXYZRGBA>::update’ requires ‘template<>’ syntax
void OpenNISegmentTracking<pcl::PointXYZRGBA>::update(const sensor_msgs::PointCloud2ConstPtr &input_cloud)
^
/hri/localdisk/markus/ros-alex/src/ball_tracking/ball_tracking_cloud/src/particle_detector.cpp:38:1: error: expected ‘}’ at end of input
} // end of namespace
^
I am not sure why I get this error..... I guess it has something to do with the fact that I use a template class ..... but I am not sure about this....
Any help would be great!
Your OpenNISegmentTracking is what in c++ terms is called a full template specialization.
In other words, it's a version of your template that will be invoked, only when the template parameter is a pcl::PointXYZRGBA.
The proper syntax for such a definition is
template <>
void OpenNISegmentTracking<pcl::PointXYZRGBA>::update(const sensor_msgs::PointCloud2ConstPtr &input_cloud)
{
...
}
You need this syntax for the function name:
template<>
void OpenNISegmentTracking<pcl::PointXYZRGBA>::update(const sensor_msgs::PointCloud2ConstPtr &input_cloud)
{
// ...
}
I'm unable to SWIG wrap a function that returns a map of pointers to class instances. I get compile errors when the generated SWIG code is compiled.
error C2039: 'type_name' : is not a member of 'swig::traits<Bar>'
Here is my .i file
class Foo
{
...
};
class Bar
{
...
};
%template(MapFooPtrBarPtr) std::map<Foo*, Bar*>;
std::map<Foo*, Bar*> GetMap();
Add the following typemap code to the .i file before the %template. Note the lack of '*' after the class name in the return string.
%{
namespace swig {
template <> struct traits<Bar>
{
typedef pointer_category category;
static const char* type_name()
{
return "Bar";
}
};
}
%}
Got the solution from: http://swig.10945.n7.nabble.com/std-containers-and-pointers-td3728.html
I have a C++/Win32/MFC project in Visual Studio 2008, and I'm getting a strange error message when I compile it.
I've created a small project to demonstrate the problem, and the main code is
#ifndef _MyObject_h
#define _MyObject_h
class MyObject
{
public:
MyObject()
{
}
};
#endif // _MyObject_h
// --- END MyObject.h
// --- BEGIN ObjectData.h
#ifndef _ObjectData_h
#define _ObjectData_h
template <typename DataPolicy>
class ObjectData
{
public:
DataPolicy *data;
ObjectData() :
data(NULL)
{
}
ObjectData(const ObjectData<DataPolicy> ©) :
data(copy.data)
{
}
ObjectData<DataPolicy> & operator=(const ObjectData<DataPolicy> ©)
{
this->data = copy.data;
return *this;
}
};
#endif // _ObjectData_h
// --- END ObjectData.h
// --- BEGIN Tool.h
#ifndef _Tool_h
#define _Tool_h
#include "ObjectData.h"
template <typename ObjectPolicy>
class Tool
{
private:
ObjectData<typename ObjectPolicy> _object;
public:
Tool(ObjectData<typename ObjectPolicy> obj);
};
#endif // _Tool_h
// --- END Tool.h
// --- BEGIN Tool.cpp
#include "stdafx.h"
#include "Tool.h"
template <typename ObjectPolicy>
Tool<ObjectPolicy>::Tool(ObjectData<typename ObjectPolicy> obj) :
_object(obj)
{
}
// --- END Tool.cpp
// --- BEGIN Engine.h
#ifndef _Engine_h
#define _Engine_h
#include "Tool.h"
#include "MyObject.h"
class Engine
{
private:
MyObject *_obj;
public:
Engine();
~Engine();
void DoSomething();
};
#endif // _Engine_h
// --- END Engine.h
// --- BEGIN Engine.cpp
#include "stdafx.h"
#include "Engine.h"
Engine::Engine()
{
this->_obj = new MyObject();
}
Engine::~Engine()
{
delete this->_obj;
}
void Engine::DoSomething()
{
ObjectData<MyObject> objData;
objData.data = this->_obj;
// NEXT LINE IS WHERE THE ERROR OCCURS
Tool< ObjectData<MyObject> > *tool = new Tool< ObjectData<MyObject> >(objData);
}
// --- END Engine.cpp
Errors:
Engine.cpp
c:\projects\myproject\myproject\engine.cpp(18) : error C2664: 'Tool::Tool(ObjectData)' : cannot convert parameter 1 from 'ObjectData' to 'ObjectData'
with
[
ObjectPolicy=ObjectData,
DataPolicy=ObjectData
]
and
[
DataPolicy=MyObject
]
and
[
DataPolicy=ObjectData
]
No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1>Build log was saved at "file://c:\Projects\MyProject\MyProject\Debug\BuildLog.htm"
MyProject - 1 error(s), 0 warning(s)
Thanks for any help.
There are a few problems with your code. First of all, you are using the typename keyword in a wrong way. typename can be used only when qualified type names are used (and is required when the type names are dependent), which is not your case:
template <typename ObjectPolicy>
class Tool
{
private:
ObjectData<typename ObjectPolicy> _object; // "typename" is not needed!
public:
Tool(ObjectData<typename ObjectPolicy> obj); // "typename" is not needed!
};
The problem you complain about, however, is in your instantiation of the Tool class template:
Tool< ObjectData<MyObject> > *tool = new Tool< ObjectData<MyObject> >(objData);
Your Tool<> template contains a member variable of type ObjectData<ObjectPolicy>, where ObjectPolicy is the class template parameter. However, in the line above you instantiate Tool with ObjectData<MyObject> as a parameter. This means your member variable will have type ObjectData<ObjectData<MyObject>>, and this will also be the type of the constructor's parameter.
Because of this, you are trying to invoke a constructor which accepts an ObjectData<ObjectData<MyObject>> with an argument of a mismatching type ObjectData<MyObject>. Hence, the error you get.
You should change your instantiation into:
Tool< MyObject > *tool = new Tool< MyObject >(objData);
Another problem is that you have the definition of Tool's member functions in a separate .cpp files. You should not do that: the linker won't be able to see it when processing a separate translation unit.
To solve this problem, put the definitions of your class template's member functions into the same header where the class template is defined (Tool.h in your case).
Tool< ObjectData<MyObject> > *tool = new Tool< ObjectData<MyObject> >(objData);
template <typename ObjectPolicy>
Tool<ObjectPolicy>::Tool(ObjectData<typename ObjectPolicy> obj) :
_object(obj)
{
}
It seems to me you might not really understand how templates work.
Check out the following C++ Templates
What you currently have is invalid C++ syntax. Take a look and give it another shot.
so im having a bit of problem with my ResourceManager class for a game im working on with c++.
so i tried to make a template function out of my regular addImage function so it will add sounds too but i got some errors which i cant really handle can you guys help me? :D
.hpp
#ifndef RESOURCE_MANAGER_HPP
#define RESOURCE_MANAGER_HPP
#include "Image.cpp"
#include "SoundBuffer.cpp"
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
typedef std::map<std::string, sz::Image*> ImagesContainer;
typedef std::map<std::string, sz::Image*>::iterator ImagesContainerIt;
typedef std::map<std::string, sz::SoundBuffer*> SoundsContainer;
typedef std::map<std::string, sz::SoundBuffer*>::iterator SoundsContainerIt;
typedef std::map<std::string, sf::Music*> MusicContainer;
typedef std::map<std::string, sf::Music*>::iterator MusicContainerIt;
namespace sz
{
// meanwhile this class is only for images, need to edit later for
// it to be also able to load sounds, etc...
class ResourceManager{
private:
ResourceManager() {};
ResourceManager(ResourceManager const&) {};
static ResourceManager *rm;
// add functions and variables here
ImagesContainer imagesContainer;
SoundsContainer soundsContainer;
MusicContainer musicContainer;
template <class type>
void AddNew(std::string imagePath);
public:
static ResourceManager *Instance();
// add functions here
template <class type>
type *Get(std::string imagePath);
};
}
#endif
.cpp
#include "ResourceManager.hpp"
#include <typeinfo>
namespace sz
{
ResourceManager *ResourceManager::rm = NULL;
ResourceManager *ResourceManager::Instance()
{
if (!rm)
rm = new ResourceManager;
return rm;
}
template <class type>
void ResourceManager::AddNew(std::string filePath)
{
type *item = new type(filePath);
if(typeid(type) == typeid(sz::Image))
imagesContainer[filePath] = item;
else if(typeid(type) == typeid(sz::SoundBuffer))
soundsContainer[filePath] = item;
else
return;
}
template <class type>
type *ResourceManager::Get(std::string filePath)
{
if(typeid(type) == typeid(sz::Image))
{
ImagesContainerIt it = imagesContainer.find(filePath);
if(it == imagesContainer.end())
{
AddNew<type>(filePath);
}
it = imagesContainer.find(filePath);
return it->second;
}
else if(typeid(type) == typeid(sz::SoundBuffer))
{
SoundsContainerIt it = soundsContainer.find(filePath);
if(it == soundsContainer.end())
{
AddNew<type>(filePath);
}
it = soundsContainer.find(filePath);
return it->second;
}
else
return NULL;
}
}
the errors #_#
g++ -Wall -c "Sprite.cpp" (in directory: /home/gannash/Desktop/Open Heroes/Engine)
In file included from Sprite.cpp:2:0:
ResourceManager.cpp: In member function ‘type* sz::ResourceManager::Get(std::string) [with type = sz::Image, std::string = std::basic_string<char>]’:
Sprite.cpp:10:65: instantiated from here
ResourceManager.cpp:50:15: error: cannot convert ‘sz::SoundBuffer*’ to ‘sz::Image*’ in return
ResourceManager.cpp: In member function ‘void sz::ResourceManager::AddNew(std::string) [with type = sz::Image, std::string = std::basic_string<char>]’:
ResourceManager.cpp:36:5: instantiated from ‘type* sz::ResourceManager::Get(std::string) [with type = sz::Image, std::string = std::basic_string<char>]’
Sprite.cpp:10:65: instantiated from here
ResourceManager.cpp:23:4: error: cannot convert ‘sz::Image*’ to ‘std::map<std::basic_string<char>, sz::SoundBuffer*>::mapped_type {aka sz::SoundBuffer*}’ in assignment
ResourceManager.cpp: In member function ‘type* sz::ResourceManager::Get(std::string) [with type = sz::Image, std::string = std::basic_string<char>]’:
ResourceManager.cpp:55:2: warning: control reaches end of non-void function [-Wreturn-type]
Compilation failed.
Ok, this is my idea after having a look at the code and error messages.
You cannot return Image and Sound from the same function like that. They are individual types. And you have to specify what type is going to be returned. When you put the if/else in your template it still will check to see if it can return all those types, and that will fail.
You have to return a BaseClass*(or whatever you want to call it) that both Image and Sound inherits from.
The templated function have to be completely defined for the compiler to able to use them. That means you have to move the body of those function from the source file to the header file.
Edit:
You have to check the how you use the template class. See for example this error message:
ResourceManager.cpp:50:15: error: cannot convert ‘sz::SoundBuffer*’ to ‘sz::Image*’ in return
Unless sz::SoundBuffer inherits from sz::Image you have a mismatch between types.
"Compile-time if" is done via template partial specialization. But here it's not even needed:
template<typename type> struct Container {
static std::map<std::string, type*> container;
};
std::map<std::string, sz::Image*>& ImagesContainer = Container<sz::Image>::container;
// etc...
template <class type>
void ResourceManager::AddNew(std::string filePath)
{
type *item = new type(filePath);
Container<type>::container[filePath] = item;
}