Reputation: 7387
I have a header file, that is for a GNU Radio Signal Processing block, and to define a C++ API. As I wrote in the comments it uses a "friend" definition in order to handle Boost Shared Pointers in a secure manner, so that no accidental raw pointers occur (access to private constructors).
I cannot really say why this fails. It seems to be related with the identifiers used at the constructors. The class definitions btw. ends with a ";" ;)
My build error message, is (I marked the lines in question with [point n].
cogra_binary_slicer.h:64:66: error: return type specification for constructor invalid [point 1] cogra_binary_slicer.cc: In function ‘cogra_binary_slicer_sptr cogra_binary_slicer()’: cogra_binary_slicer.cc:42:41: error: expected type-specifier [POINT 2] before ‘cogra_binary_slicer’ cogra_binary_slicer.cc:42:41: error: expected ‘)’ before ‘cogra_binary_slicer’ cogra_binary_slicer.cc:42:63: error: could not convert ‘gnuradio::get_initial_sptr(T*) with T = int’ from ‘boost::shared_ptr’ to ‘cogra_binary_slicer_sptr {aka boost::shared_ptr}’
That however narrows it down to three files.
The header, cogra_binary_slicer.h:
#ifndef INCLUDED_COGRA_BINARY_SLICER
#define INCLUDED_COGRA_BINARY_SLICER
#include <cogra_api.h>
#include <gr_block.h>
class cogra_binary_slicer;
typedef boost::shared_ptr<cogra_binary_slicer> cogra_binary_slicer_sptr;
/*!
* \brief Return a shared_ptr to a new instance of cogra_binary_slicer.
*
* To avoid accidental use of raw pointers, cogra_binary_slicer's
* constructor is private. cogra_binary_slicer is the public
* interface for creating new instances.
*/
COGRA_API cogra_binary_slicer_sptr cogra_binary_slicer ();
class COGRA_API cogra_binary_slicer : public gr_block
{
private:
// The friend declaration allows cogra_binary_slicer to
// access the private constructor.
// [POINT 1]
friend COGRA_API cogra_binary_slicer_sptr cogra_binary_slicer ();
cogra_binary_slicer (); // private constructor
public:
~cogra_binary_slicer (); // public destructor
// Where all the action really happens
int general_work (int noutput_items,
gr_vector_int &ninput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
}; // yes
#endif /* INCLUDED_COGRA_BINARY_SLICER */
cogra_binary_slicer.cc, where the instance is created (which fails). Point of failure marked with [POINT 2]:
#include <cogra_binary_slicer.h>
#include <gr_io_signature.h>
/*
* Create a new instance of cogra_binary_slicer and return
* a boost shared_ptr. This is effectively the public constructor.
*/
cogra_binary_slicer_sptr
cogra_binary_slicer ()
{
return gnuradio::get_initial_sptr(new cogra_binary_slicer ()); **[POINT 2]**
}
And the API header, cogra_api.h:
#ifndef INCLUDED_COGRA_API_H
#define INCLUDED_COGRA_API_H
#include <gruel/attributes.h>
#ifdef gnuradio_cogra_EXPORTS
# define COGRA_API __GR_ATTR_EXPORT
#else
# define COGRA_API __GR_ATTR_IMPORT
#endif
#endif /* INCLUDED_COGRA_API_H */
I attached that much source because I can't narrow down why the compilation fails at that specific locs.
Some pointers why my return type is invalid could be helpful.
Upvotes: 2
Views: 1214
Reputation: 254691
Within the function definition, cogra_binary_slicer
refers to the function, not the class.
You need to change new cogra_binary_slicer
to new class cogra_binary_slicer
.
However, within the class definition, cogra_binary_slicer
will always refer to the class, so I don't think there is any way to make the function a friend. So I think your only choice is to give the class and function different names. This will also help to reduce confusion.
Upvotes: 0
Reputation: 22187
You should rename your class or cogra_binary_slicer
function.
Consider this example which compiles fine:
class A;
A* B();
class A{
friend A* B();
A(){};
public:
A(int i){}
};
A* B(){ return new A(); }
and this which fails with error "error C2380: type(s) preceding 'A' (constructor with return type, or illegal redefinition of current class-name?)"
class A;
A* A();
class A{
friend A* A();
A(){};
public:
A(int i){}
};
A* A(){ return new A(); }
Also, you should consider to use public static member function in your class:
class A{
A(){};
public:
A(int i){}
static A* getInstance(){ return new A(); }
};
Upvotes: 0
Reputation: 64273
Rename your creation function to something other then class name :
friend COGRA_API cogra_binary_slicer_sptr cogra_binary_slicer ();
Otherwise, the compiler might see it as a constructor with areturn type.
Upvotes: 3