2

so this works fine:

template<class V>
void bar(V v1, V v2) {
}

template <class T>
void foo(T t1, T t2) {
    bar(t1, t2);
}

int main() {
    foo(5, 6);
}

but if i change the order of foo and bar like this:

template <class T>
void foo(T t1, T t2) {
    bar(t1, t2);
}

template<class V>
void bar(V v1, V v2) {
}

int main() {
    foo(5, 6);
}

i get a compilation error:

see reference to function template instantiation 'void foo(T,T)' being compiled

Error C3861 'bar': identifier not found 'bar':

'bar' function was not declared in the template definition context and can be found only via argument-dependent lookup in the instantiation context

what is causing this? what is the hidden problem? what rule of cpp have i broke this time?
I will appreciate insights on the matter

EDIT: thank you for your comments, but for some reason changing bar to swap cause error:
this code:

template<class V>
void swap(V v1, V v2) {
}

template <class T>
void foo(T t1, T t2) {
    swap(t1, t2);
}

int main() {
    foo(5, 6);
}

generates this error:

while trying to match the argument list '(T, T)' see reference to function template instantiation 'void foo(T,T)' being compiled
or 'void std::swapstd::ios_base::iostate,0(_Ty &,_Ty &) noexcept' could be 'void swap(V,V)' Error C2668 'swap': ambiguous call to overloaded function

I know that swap is not a key word in c++.
What is causing this error? i have written this code in a brand new project and it still doesn't work

  • 4
    In C++ you must always declare symbols before they are used. In the second example, when the compiler see the call to `bar` it doesn't know what `bar` is. That the functions are templates is irrelevant to this problem. Honestly, this should have been taught in every book, tutorial or class. – Some programmer dude Aug 31 '20 at 09:50
  • 1
    If you really want them in this order, you can add a [forward declaration](https://godbolt.org/z/f391dK) – Benny K Aug 31 '20 at 09:51
  • 3
    You broke the same rule as you would if they weren't templates. – molbdnilo Aug 31 '20 at 09:56
  • I'm guessing you have dependency cycle in your code and you have reduced problem to much providing this question (it is good that you try to reduce the issue to minimum). So I would recommend you to ask new question (provide link here), which will present the cycle and why you need it. We will show you how to nicely break this dependency cycle (they are bad for code quality) in this new question. – Marek R Aug 31 '20 at 10:30
  • kindly have a look at my edit – forstack overflowizi Aug 31 '20 at 14:53

1 Answers1

1

You would get a compiler error from this code for the very same reason:

void foo(T t1, T t2) {
    bar(t1, t2);
}

void bar(V v1, V v2) {
}

int main() {
    foo(5, 6);
}

You cannot call bar before it is declared. Solutions: Either declare bar before you call it, or move the whole definition of bar before foo.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • @forstackoverflowizi new questions should go to new questions. This is the answer to your old question. Anyhow, the problem is that you should not write your own `swap` because there is `std::swap`, if you still do it you need to pick one of them `::swap` or `std::swap` – 463035818_is_not_an_ai Aug 31 '20 at 14:56
  • thank you very very much!!! i just cannot believe the the std namespace will mess up with my code like that. – forstack overflowizi Aug 31 '20 at 18:59
  • @forstackoverflowizi [Why is “using namespace std;” considered bad practice?](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) – 463035818_is_not_an_ai Aug 31 '20 at 20:38