Consider the following stripped-down example of a (templated) C++ structure for square matrices (it doesn't need to be templated for the problem to occur):
#include <array>
#include <complex>
using namespace std;
double conj (double &x) { return x; };
template <typename T, int N>
struct matrix: array<T,N*N> {
void conj() {
for (int ij=0; ij<100; ++ij) {
T z = (*this)[ij];
(*this)[ij] = conj(z);
}
}
};
int main() {
matrix<double,10> a;
a.conj();
return 0;
}
I want to implement a method that performs matrix complex conjugation, using the name .conj() to coincide with the naming system used in the < complex > library. However, I get the following error:
$ g++ example.cpp -std=c++11
example.cpp: In instantiation of ‘void matrix<T, N>::conj() [with T = double; int N = 10]’:
example.cpp:19:12: required from here
example.cpp:12:26: error: no matching function for call to ‘matrix<double, 10>::conj(double&)’
(*this)[ij] = conj(z);
^
example.cpp:12:26: note: candidate is:
example.cpp:9:10: note: void matrix<T, N>::conj() [with T = double; int N = 10]
void conj() {
^
example.cpp:9:10: note: candidate expects 0 arguments, 1 provided
The compiler doesn't seem to recognize the function conj(double&) called inside the method of the same name, and defined before the structure. Instead, it tries to call the method conj().
Why isn't the compiler able to resolve this naming conflict, and what would be the solution that preserves the naming? Of course, if I change the name of the method to something different to conj, the code compiles and runs normally.
The member function hides functions of the same name in a wider scope.
Use the qualified name ::conj
to refer to the function in the global namespace.