Overload functions by dimension of vector

In summary: There is also a std::negate, which is probably found via argument dependent lookup?Yes, std::negate is a struct.
  • #1
Pete5876
7
0
C++:
vector<OP> negate (vector<OP> a) {
    a.insert(a.begin(), neg);
    return a;
}

vector<vector<OP>> negate (vector<vector<OP>> a) {
    for (int i=0; i<a.size(); i++)
        a[i] = negate(a[i]); // reference to 'negate' is ambiguous?
    return a;
}

OP is an enum here. Why can't C++ distinguish between these two? One function takes a two-dimensional vector of OP whereas the other one takes a three-dimensional vector of OP. I can't flatten that 3D vector because it's elements aren't of the same size.
 
Technology news on Phys.org
  • #2
On line 2, what is "neg"?
Once I resolved that, it compiled for me.

Code:
#include <vector>
using namespace std;

class OP {
public:
   int n1;
};

vector<OP> negate (vector<OP> a) {
   for(int i=0; i<a.size(); i++)
      a[i].n1 = -a[i].n1;
   return a;
}

vector<vector<OP>> negate (vector<vector<OP>> a) {
   for(int i=0; i<a.size(); i++)
      a[i] = negate(a[i]);
   return a;
}
 
  • #3
C++:
#include <iostream>
#include<vector>
using namespace std;

vector<int> negate (vector<int> a) {
    a.insert(a.begin(), -1);
    return a;
}

vector<vector<int>> negate (vector<vector<int>> a) {
    for (int i=0; i<a.size(); i++)
        a[i] = negate(a[i]); // reference to 'negate' is ambiguous?
    return a;
}

int main() {
    vector<vector<int>> r = {{3,4,5,6},{4,4,5,6,7,4}};
    r=negate(r);
    return 0;
}

I provided a more complete and simpler code. In line 12 the compilers (Dev, Visual Studio and several online C++ compilers), they're all find that "ambiguous". But since a is of type <vector<vector<int>> then a must be of type vector<int>, right? Negate function adds a -1 value at the beginning of every vector.
 
  • #4
Your code works for me.
Are you creating a vector<int> somewhere else in your build?
 
  • #5
It's a complete code. Try pasting the code from my last post into https://www.onlinegdb.com/online_c++_compiler or any other IDE and the error comes out the same every time "main.cpp:12:16: error: reference to ‘negate’ is ambiguous".
 
  • #6
There is also a std::negate, which is probably found via argument dependent lookup? Try replacing the "using namespace std" by "using std::vector".
 
  • Like
Likes Pete5876
  • #7
I'm using MS Visual Studio 2022.
Vector.png
 
  • #8
BTW, whatever compiler version onlinegdb uses, it also compiles if you don't include iostream. I think the lessons here are 1) avoid "using namespace std;" and 2) don't include what you don't use.
 
  • Like
Likes Jarvis323
  • #9
vis_insita said:
I think the lessons here are 1) avoid "using namespace std;" and 2) don't include what you don't use.
Excellent advice.
 
  • Like
Likes Vanadium 50 and pbuk
  • #10
CLHEP, when faced with this, decided they wanted different classes for 2-vectors, 3-vectors and 4-vectors. One reason is that you do different things with them: the norm of a 4-vector is not the same as a 3-vector. Part of the reason is that it is not clear what is meant when you combine them: when you add a 2-vector to a 3-vector, how do you promote it? Set the z-component to zero? What's specila about z?

I would say the trick to OOP is to make sure your objects are neither too general nor too specific. Other people have found an arbitrarily dimensioned vector to be too general.
 
  • Like
Likes pbuk
  • #11
.Scott said:
I'm using MS Visual Studio 2022.
It depends on how the standard library implementers organize their header files. gcc apparently declares std::negate in a header used by std::string, which is included via iostream. You can get this information from the compiler output on onlinegdb:
main.cpp:19:7: error: reference to ‘negate’ is ambiguous
19 | r=negate(r);
| ^~~~~~
In file included from /usr/include/c++/11/string:48,
from /usr/include/c++/11/bits/locale_classes.h:40,
from /usr/include/c++/11/bits/ios_base.h:41,
from /usr/include/c++/11/ios:42,
from /usr/include/c++/11/ostream:38,
from /usr/include/c++/11/iostream:39,
from main.cpp:2:
The latest gcc version also pulls std::negate in together with the vector header. (It can also depend on the language standard used.) So, other than renaming "negate" there is no way around removing the using directive in this example, in which it is also completely unnecessary.

EDIT:
vis_insita said:
There is also a std::negate, which is probably found via argument dependent lookup?
I just realized that std::negate is a struct not a function. Also it can be found by ordinary name lookup, since the unqualified name is already visible thanks to the using directive. At any rate, ADL has nothing to do with it.
 
Last edited:
  • Like
Likes Jarvis323

1. What is the purpose of overloading functions by dimension of vector?

Overloading functions by dimension of vector allows for different versions of the same function to be used depending on the dimension of the vector being passed in. This allows for more flexibility and efficiency in code, as specific functions can be created for different vector dimensions.

2. How does overloading functions by dimension of vector work?

Overloading functions by dimension of vector works by creating multiple versions of the same function with different parameters for different vector dimensions. The correct version of the function is then called based on the dimension of the vector being passed in.

3. Can any function be overloaded by dimension of vector?

Yes, any function that takes a vector as a parameter can be overloaded by dimension of vector. This includes both user-defined functions and built-in functions.

4. What are the benefits of overloading functions by dimension of vector?

Overloading functions by dimension of vector can lead to more efficient and readable code, as specific functions can be created for different vector dimensions. It also allows for more flexibility, as new versions of the function can be added for different dimensions without affecting the existing code.

5. Are there any limitations to overloading functions by dimension of vector?

One limitation of overloading functions by dimension of vector is that it can only be used for functions that take a vector as a parameter. It also requires careful naming and organization of the different versions of the function to avoid confusion. Additionally, overloading can only be used for functions with different parameters, not just different return types.

Similar threads

  • Programming and Computer Science
2
Replies
52
Views
3K
  • Programming and Computer Science
Replies
2
Views
377
  • Programming and Computer Science
Replies
23
Views
2K
  • Programming and Computer Science
Replies
15
Views
2K
  • Programming and Computer Science
Replies
12
Views
1K
  • Quantum Physics
2
Replies
61
Views
1K
Replies
10
Views
158
Replies
17
Views
2K
Replies
9
Views
1K
  • Programming and Computer Science
Replies
2
Views
684
Back
Top