wishi
wishi

Reputation: 7387

Return type definition for a constructor - howto fix this header

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

Answers (3)

Mike Seymour
Mike Seymour

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

Nemanja Boric
Nemanja Boric

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

BЈовић
BЈовић

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

Related Questions