0

I am new to templates in C++ and i attempted to make one with two numeric values:

template <
    typename T, typename T2,
    typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type,
    typename = typename std::enable_if<std::is_arithmetic<T2>::value, T2>::type>
T distance(vertex<T2>& p_Vertex1, vertex<T2>& p_Vertex2) {
  return sqrt(pow((p_Vertex2.x - p_Vertex1.x), 2) +
              pow((p_Vertex2.y - p_Vertex1.y), 2));
}

Errors:

1> C: \ Users \ User \ Desktop \ Library \ src \ vertex.cpp (4): warning C4348: 'distance': redefinition of the default parameter. Parameter 3.
1> C: \ Users \ User \ Desktop \ Library \ include \ Utils \ vertex.h (30): message: see the declaration of 'distance'
1> C: \ Users \ User \ Desktop \ Library \ src \ vertex.cpp (4): warning C4348: 'distance': redefinition of the default parameter. Parameter 4.
1> C: \ Users \ User \ Desktop \ Library \ include \ Utils \ vertex.h (30): message: see the declaration of 'distance'

this function is declared in vertex.h and defined in vertex.cpp; vertex is a template class that accepts a numeric value.

How am i using it:

    vertex<double> v1(9.34342342, 5.34);
    vertex<double> v2(69.67, 5.45);

    float dist = distance<float, double>(v1, v2);
    std::cout << "Distance: " << dist << std::endl;


Solved:

I solved moving the template function the same header file.

Coral Kashri
  • 3,436
  • 2
  • 10
  • 22
  • 5
    "I am new to templates in C++" - then you should probably wait a few months/years before you dive into something like `template::value, T>::type, typename = typename std::enable_if::value, T2>::type> T distance(vertex& p_Vertex1, vertex& p_Vertex2)`.. – Jesper Juhl May 22 '20 at 19:41
  • 2
    Do you have `using namespace std;` in your code? Then your function perhaps collide with [`std::distance`](https://en.cppreference.com/w/cpp/iterator/distance)? Also see [Why is “using namespace std;” considered bad practice?](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) – Some programmer dude May 22 '20 at 19:42
  • 3
    Also, please [edit] your question to include a [mcve]. And copy-paste the full and complete build output of that example so we can see the full error output. – Some programmer dude May 22 '20 at 19:43
  • 3
    It's usually a good idea to copy-and-paste the error message into your question. Typing the error message might inadvertently change something. (For example, it is unlikely that your compiler used the non-word "ridefinition" in the error message.) – JaMiT May 22 '20 at 19:44
  • no i don't have using namespace std; in my code –  May 22 '20 at 19:49
  • 2
    Not the direct cause of your current problem but see https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file – Alan Birtles May 22 '20 at 19:55
  • Please share a complete example, including the call to this template that fails. This seems to [work](https://godbolt.org/z/ZhbX39) for me. – cigien May 22 '20 at 20:04
  • 2
    As the error message tells you you define the default parameter in the declaration **and** in the definition. When you have separate declaration and definition put the default parameter value in the declaration only. That being said with you need to implement the templates in the header. – bolov May 22 '20 at 20:17
  • "*this function is declared in vertex.h and defined in vertex.cpp*" - [that doesn't work for templates](https://stackoverflow.com/questions/495021/), only for non-templates. – Remy Lebeau May 22 '20 at 20:20
  • 1
    @JesperJuhl I completely disagree. Why wait years? Practice, practice, practice! The more the better. And besides, the OP's example it's not even that complicated. It's a simple template with `enable_if` SFINAE. – bolov May 22 '20 at 20:22
  • @cigien Try this: https://wandbox.org/permlink/EtUDl1SjyXqVvja6 to reproduce the error. – Bob__ May 22 '20 at 20:24
  • 1
    I fixed my problem; After reading why templates can't be used in source files everything is more clear. Thank you guys so much for the help. –  May 22 '20 at 20:26
  • @Bob__ oh, i see, so @ alanbirtles suggestion was the problem. – cigien May 22 '20 at 20:26
  • @cigien That's one, but see @ bolov's comment too: https://wandbox.org/permlink/5MlgTAd0rENpD3XX – Bob__ May 22 '20 at 20:31
  • @Bob__ Hmm, that doesn't seem to be the error the OP is getting though. – cigien May 22 '20 at 20:33
  • @bolov Feel free to disagree. But IMHO templates (beyond the very basic) get complicated and difficult *fast*. And even experienced professionals struggle with them. So that's why I say to expect some months/years/time-in-general to get them under your skin. *Most* programmers are not geniuses, and learning C++ templates takes time. – Jesper Juhl May 22 '20 at 20:39
  • @cigien Well, it's a different compiler: *"error: template parameter redefines default argument"* (both [1](https://wandbox.org/permlink/EtUDl1SjyXqVvja6) and [2](https://wandbox.org/permlink/u5F9yT5fpWkF2yQI)) vs. *"redefinition of the default parameter. Parameter 3."*. – Bob__ May 22 '20 at 20:44
  • @JesperJuhl Yes, they become complicated. But they can be fun and challenging and rewarding. Just because something is complicated doesn't mean you need to stay away from it. – bolov May 22 '20 at 20:49
  • @bolov I never said "stay away from it". What I tried to say was simply "prepare to have to invest some time (possibly quite a lot) in this". – Jesper Juhl May 22 '20 at 20:51

0 Answers0