-2

I cannot compile my program with VS2015 due to a function using a templated parameter and inheritance.

The error is this one.

I'm trying to achieve the following :

class A
{
    //do something
};

class B : public A
{
    //do something
};

template <typename T>
class Foo {
    template <typename T>
    friend void function(Foo<T> & sm) {
        //do something
    }
};

void main()
{
    Foo<A> test;
    Foo<B> test2;
};

I do understand the meaning of the error, but I do not understand why it actually happens.

I suppose function is created with two different signatures :

void function(Foo<A> & sm); and void function(Foo<B> & sm);

How is that a multi-definition?

EDIT - The full error message : Error C2995 'void function(Foo<T> &)': function template has already been defined

EDIT² - From scratch enter image description here

Wassim
  • 386
  • 2
  • 15
  • 1
    What are you trying to do with `function>;`? – NathanOliver Jan 17 '19 at 15:06
  • 2
    Please provide [mcve]. There are multiple errors in the code shown, that distract from the error, that you are asking about (not that I was able to see it, in the list of errors). – Algirdas Preidžius Jan 17 '19 at 15:06
  • `function` is actually `friend std::ostream & operator<<(std::ostream & o, const Foo & sm)`, so it's basically displaying. – Wassim Jan 17 '19 at 15:13
  • I compiled your code and got no errors (after fixing the obvious missing semicolons) – Thomas Sablik Jan 17 '19 at 15:21
  • I fixed the main post. I was expecting few minutes to fix it you guys were too fast. @ThomasSablik Which compiler did you used? – Wassim Jan 17 '19 at 15:27
  • 1
    Please read (again?) about [mcve]. Honestly, the fact that the code you posted does not produce the error and the edits that significantly changed the code, suggest that the code you posted was never the one you compiled on your machine to get the reported error in the first place. Please make sure the code you post does reproduce the error, otherwise we can only do guessing but not answer the question in a meaningful way – 463035818_is_not_an_ai Jan 17 '19 at 15:27
  • I'm compiling with clang. I had to fix the template parameter because it is shadowed by the outer template parameter. Also clang does not support (or warns) `void main`: [tio](https://tio.run/##fU5LCsIwEN3nFLOSdiGCS1sC7cIL1AvENK0DzSSYqSDSs8f0g6vibAbeX3t/1IOiPsb0QoBKfASkO51aB8FZww@kXkyFEKughgv48T6g/qdlY/2g2EDJb29IWQM3uSVcnYPVuKNq5MJ0TzTUwsthC91ImtFRloxlI@EAweZbwk79DE3LCCQGq5CyfBs6B1Qy1QYufkC9AucieWL8Ag) – Thomas Sablik Jan 17 '19 at 15:31
  • the code in the screenshot is different from the posted code, there is a `` hanging around in the wild. For the posted code there are errors but not the one you report: https://wandbox.org/permlink/RBLSxEqs5dh42NPK – 463035818_is_not_an_ai Jan 17 '19 at 15:34
  • i dont know visual studio, but is it possible that the "error" is just your IDE thinking there is an error (possibly because getting confused by other errors)? IDEs try to be clever, but dont trust them, its the compiler that has to accept your code, not the IDE – 463035818_is_not_an_ai Jan 17 '19 at 15:38
  • the hanging around in the screenshot is added by IntelliSense to provide sample template arguments, I changed the screenshot so that it doesnt appear anymore (it does not affect the code in any case). This a compilation error not an IntelliSense error. Can you please define "getting confused by other errors", what other errors do you refer to? – Wassim Jan 17 '19 at 15:45

1 Answers1

2

Both Clang and MS have the same complaint. Remove the second template specifier and it will compile.

class A{};
class B : public A{};

template <typename T>
class Foo {

//  template <typename T>
    friend void function(Foo<T> & sm) {
    }
};

int main()
{
    Foo<A> test;
    Foo<B> test2;
};

T is already specified for the class Foo so its friend function is covered. You would us a second template if there were a difference at the function, like:

class A{};
class B : public A{};

template <typename T>
class Foo {

    template <typename U>
    friend void function(Foo<T> & sm, U another) {
    }
};

int main()
{
    Foo<A> test;
    Foo<B> test2;
};
lakeweb
  • 1,859
  • 2
  • 16
  • 21