I have an example C++ program (included below) that works in Visual Studio 2019 with a plain version of class1 but not with a template version of class1. Both versions work in gcc. The error message I get from Visual Studio 2019 is:
Severity: Error
Code: C2063
Description: 'ns1::operator *': not a function
My question is how does Visual Studio expect me to declare the friend operator for the template case in the example below ?
Version of code with class1 a plan class. This works on gcc and visual Studio 2019:
# include <iostream>
// begin ns1
namespace ns1 {
// begin class1
class class1 {
private:
int value_;
public:
class1(int value ) : value_(value)
{ }
int Value(void) const
{ return value_; }
}; // end class1
// forward declaration or operator
class1 operator *
(const class1& left, const class1& right);
// begin ns1
namespace ns2 {
// begin class2
class class2 {
friend ns1::class1 ns1::operator *
(const ns1::class1& left, const ns1::class1& right);
private:
int value_;
public:
class2( int value ) : value_(value)
{ }
int Value(void) const
{ return value_; }
}; // end class2
} // end ns2
class1 operator *
(const class1& left, const class1 &right)
{ ns2::class2 one(1);
// use private access to value_ to make sure friend statement working
return class1( one.value_ * left.Value() * right.Value() );
}
} // end ns1
// begin main
int main(void)
{ ns1::class1 two(2), three(3);
ns1::class1 six = two * three;
std::cout << "six.Value() = " << six.Value() << "\n";
return 0;
} // end main
Version of code with class1 a template class. This works on gcc but not in Visual Studio 2019. I am using a modified version of the Hello World console example in Visual Studio.
# include <iostream>
// begin ns1
namespace ns1 {
// begin class1
template <class Type> class class1 {
private:
Type value_;
public:
class1(Type value ) : value_(value)
{ }
Type Value(void) const
{ return value_; }
}; // end class1
// forward declaration or operator
template <class Type> class1<Type> operator *
(const class1<Type>& left, const class1<Type>& right);
// begin ns1
namespace ns2 {
// begin class2
class class2 {
friend ns1::class1<int> ns1::operator * <int>
(const ns1::class1<int>& left, const ns1::class1<int>& right);
private:
int value_;
public:
class2( int value ) : value_(value)
{ }
int Value(void) const
{ return value_; }
}; // end class2
} // end ns2
template <class Type> class1<Type> operator *
(const class1<Type>& left, const class1<Type> &right)
{ ns2::class2 one(1);
// use private access to value_ to make sure friend statement working
return class1<Type>( one.value_ * left.Value() * right.Value() );
}
} // end ns1
// begin main
int main(void)
{ ns1::class1<int> two(2), three(3);
ns1::class1<int> six = two * three;
std::cout << "six.Value() = " << six.Value() << "\n";
return 0;
} // end main