0

i have object

 template <class FLOAT>
 struct Cstruct {
       Struct1<FLOAT> _var1;
       Struct2<FLOAT> _var2;   
       Cstruct(){};
       Cstruct(Struct1 var1,Struct2 var2):_var1(var1),_var2(var2){};
};

FLOAT can be "double" or "int". Struct1 and Struct2 are also templatized with FLOAT.

now i also have a global variable declared

 Cstruct<double> globalObj_d;Cstruct<int> globalObj_i;

inside main() i have

main(){
  // some code
  if double then call func<double>();
  if int    then call func<int>();        

}

and inside templatized func() i have

template<class FLOAT> void func(){
 // some code 
 Struct1<FLOAT> var1;
 Struct2<FLOAT> var2;
 Cstruct<FLOAT> localObj(var1,var2);
 // now i want to assign "localObj" to the global object "globalObj_d"
 if double then 
     globalObj_d = localObj;
 if int then
     globalObj_i = localObj;
} 

and i get an error saying

error C2679: binary '=' : no operator found which takes a right-hand operand of type 'Cstruct<FLOAT>

does does this mean i have to explicitly write an "operator=" inside Cstruct ? my understading of templatized and global object it seems is kind of flawed. any help will greatly appreciated.

Robᵩ
  • 163,533
  • 20
  • 239
  • 308
user1612986
  • 1,373
  • 3
  • 22
  • 38
  • 4
    Please tell me what this does in C++: `if double then`. Seems you are talking different language. – ondrejdee Jun 27 '13 at 14:31
  • if statement lines are not c++, i just gave pseudocode to explain the issue. i just created a example problem to demonstrate the issue i am facing. – user1612986 Jun 27 '13 at 14:44
  • I get error C2955: 'Struct1' : use of class template requires template argument list on the second CStruct constructor - is this exactly your code? – doctorlove Jun 27 '13 at 14:46
  • strange that you got error C2955. i get error C2679: binary '=' : no operator found which takes a right-hand operand of type 'Cstruct' (or there is no acceptable conversion) with FLOAT=int d:xxx.h(201):couldbe'Cstruct&Cstruct::operator =(Cstruct &)' 1> with 1> [ 1> FLOAT=double 1> ] 1> while trying to match the argument list '(Cstruct, Cstruct)' 1> with 1> [ 1> FLOAT=double 1> ] 1> and 1> [ 1> FLOAT=int 1> ] – user1612986 Jun 27 '13 at 14:55

3 Answers3

0

In this case you might need to. See the rule of three The compiler will provide one for you if it can. You have not showed us the definitions of Struct1<FLOAT> or Struct2<FLOAT>. If it can't generate assignments for these, it can't generate one for CStruct.

While you are there, avoid the leading underscores on the variable names .

Community
  • 1
  • 1
doctorlove
  • 18,872
  • 2
  • 46
  • 62
0

The use of psudocode in your question make it difficult to understand. So let me try to boil this down a little bit in to real code. It appears that what you are trying to do is essentially something along these lines:

template <typename VAL>
class Foo
{
public:
  VAL mVal;
};

int main()
{
  Foo <int> global_i;
  Foo <double> global_d;

  Foo <double> local;

  // ...
  if (/*someConditional*/)
    global_i = local;  // <== LINE 1
  else
    global_d = local;  // <== LINE 2
}

This won't work. Note that even though only one of either LINE1 or LINE2are executed at run-time, they are both compiled at compile-time. The first one is trying to assign a Foo<int> to a Foo<double>, but the types are not compatible much in the same way that these are also not compatible:

class Gee
{
};

class Whiz
{
};

int main()
{
  Gee g;
  Whiz w;

  Gee local;
  local = w;  // <<< INCOMPATIBLE TYPES
}

In order to make this work, you will either need to provide some kind of conversion operator on Foo to convert to another type of Foo, for example:

template <typename VAL>
class Foo
{
public:
  template <typename OTHER> operator Foo <OTHER> () const 
  {
    Foo <OTHER> ret;
    // ...
    return ret;
   }
};

...or perhaps provide two separate functions to do the assignments; one for a Foo<int>, and another for a Foo<double>.

John Dibling
  • 99,718
  • 31
  • 186
  • 324
  • I read the if part as being in a template, so the local is of type typename FLOAT, but the pseudocode is making this hard to follow – doctorlove Jun 27 '13 at 15:09
0

First: if a type might be either floating point or integer, don't name it "FLOAT". You could use the standard T, or perhaps something like Number, but definitely avoid FLOAT.

As to the real question (or my guess at the real question): almost any time you think in terms of if (type == X) or switch (type) sort of code (at least in C++), you're making a fundamental mistake -- you can probably manage to do that if you want to badly enough, but it's not how C++ is intended to work.

In this case, there's a fairly easy way to avoid it: create another template. In particular, you can overload a couple of function templates, one for each global you want to support:

#include <string>
#include <iostream>

int i_global;
double d_global;

template <class T>
void assign(T in) { 
    // this function should never be called.
    assert(false);
}

template<>
void assign<int>(int in) { 
    i_global = in;
}

template<>
void assign<double>(double in) {
    d_global = in;
}

// for the moment, func(input) will just call assign(input):
template <class T>
void func(T input) {
    assign<T>(input);
}

int main(int argc, char **argv) { 
    if (argc != 2) {
        std::cerr << "Usage: trash <number>\n";
        return EXIT_FAILURE;
    }

    std::string in(argv[1]);

    // see if the input contains a decimal point, and act accordingly:
    if (in.find('.') != std::string::npos)
        func(std::stod(in));
    else
        func(std::stoi(in));

    // show the results -- the values of the globals:
    std::cout << "Result:\ndouble: " << d_global << "\nint: " << i_global << "\n";
    return 0;
}

I get the result I'd hope for -- if I enter something like 1.5 it gets assigned to the double; if I enter something like 123 it gets assigned to the int.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111