Isn't a class unable to reference itself without hitting a snag?

I've done my best to be clear in the title, but I'm fully aware I've done a bad job. So here some more description of the problem.

I'm developing a class that manages square block-matrices, to make the inversion of said matrices an automated job (I haven't been able to find anything fitting in some already existing library: if you can address me to something ready made it can help, too).

One of the key feature of this class should be its ability to see its blocks as block-matrices themselves. It does not memorize them as instances of the class (that would be the same as a recursive function calling itself infinite times), but it has a method that returns an instance of the class constructed from one of the blocks, which are simple arrays.
I haven't been able to see anything wrong with this approach: a method returning an instance of the class isn't unheard of. Is it?

Anyway, the compiler (TDM-GCC 4.8.1 32-bit) seems to agree with me, because it doesn't see it as an error. Unless I try to use this method as the argument of a function that takes a reference to the class, then the compiler is at a loss and claims it can convert the types from "class<template>" to "class<template>&". In other words, the compiler doesn't want to take the reference of the returned object.
Note that the returned object is not a reference, it is a plain old copy of an internal object. It's the only way to generate an independent object which won't be hogging the memory after its lifespan is over.

Here's the code structure that's creating problems:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
template<class boom>
class theClass{
  public:
    theClass();
    theClass( boom* data, int size );
    theClass( theClass<boom>& );

    //various operators, all taking references
    //as arguments

    //some methods
    theClass<boom> get_block( int whichOne );
    //...
  private:
    boom* _block_a;
    boom* _block_b;
    boom* _block_c;
    boom* _block_d;

    int _size; /*the matrix is square _size*_size*/
    //utilities and tools, not relevant here
};

//...
template<class boom>
theClass<boom> theClass<boom>::get_block( int whichOne ){
  boom* data;

  switch( whichOne ){
    case 0:
      data = _block_a;
      break;
    //more of the same for the subsequent cases
  };

  theClass<boom> result( data, _size/2 );
  return result;


Now, the constructor invoked here does work (already tested).
Why on Earth do I get errors when I try to use the method?
If i pass it (like object.get_block( 0 )) to a function that takes a theClass<someType> argument someFunc( theClass<someType> arg ), the compiler tells me that he doesn't find a copy constructor that accepts not the reference, but directly he type: theClass<someType>::theClass( theClass<someType>) (the language doesn't allow for such a constructor to be specified).
If i try to pass it to a function that accepts a referencesomeFunc( theClass<someType>& arg ), it tells me that I can't pass the reference to a temporary object -when there aren't temporary objects around. Unnamed, perhaps, but not temporary.

I am currently trying to elude the problem, but I'd like to read your ideas on it nevertheless. Thanks.
Last edited on
claims it can convert the types from "class<template>" to "class<template>&". In other words, the compiler doesn't want to take the reference of the returned object.

Well it's not possible to bind a non-const lvalue reference to a temporary object. Either store it in an object, or bind a reference to const.

there aren't temporary objects around. Unnamed, perhaps, but not temporary

It's a little hard to say what you're referring to since you're not showing the code that generates the error, but the result of a function call to any function whose return type is not a reference is a temporary object.
Last edited on
When you call this function the return value will be a temporary object. A reference to a non-const object can't bind to a temporary object. If you change the parameter type of the copy constructor to const it should work.

 
theClass(const theClass<boom>& );
Thank you all for your answers.
The solution provided by Peter87 did work: now I don't get any compilation error.

Thank you also to clarify that the return value of that function is indeed a temporary object.
Topic archived. No new replies allowed.