Visual Studio 2019 C ++ не распознает друзей по шаблону - PullRequest
0 голосов
/ 06 августа 2020

У меня есть пример программы на C ++ (см. Ниже), которая работает в Visual Studio 2019 с простой версией class1, но не с версией шаблона class1. Обе версии работают в g ​​cc. Сообщение об ошибке, которое я получаю от Visual Studio 2019:

Severity:    Error
Code:        C2063
Description: 'ns1::operator *': not a function

Мой вопрос: как Visual Studio ожидает, что я объявлю оператор друга для случая шаблона в приведенном ниже примере?

Версия кода с классом 1 класс плана. Это работает в g ​​cc и Visual Studio 2019:

# include <iostream>

// begin ns1
namespace ns1 {
    // begin class1
     class class1 {
    private:
       int value_;
    public:
       class1(int value ) : value_(value)
       { }
       int Value(void) const
       {   return value_; }
    }; // end class1
    // forward declaration or operator
     class1 operator * 
    (const class1& left, const class1& right);
    // begin ns1
    namespace ns2 {
        // begin class2
        class class2 {
            friend ns1::class1 ns1::operator * 
            (const ns1::class1& left, const ns1::class1& right);
        private:
            int value_;
        public:
            class2( int value ) : value_(value)
            { }
            int Value(void) const
            {   return value_; }
        }; // end class2
    } // end ns2
     class1 operator *
    (const class1& left, const class1 &right)
    {   ns2::class2 one(1);
    // use private access to value_ to make sure friend statement working
    return class1( one.value_ * left.Value() * right.Value() );
    }
} // end ns1

// begin main
int main(void)
{   ns1::class1 two(2), three(3);
    ns1::class1 six = two * three;
    std::cout << "six.Value() = " << six.Value() << "\n";
    return 0;
} // end main

Версия кода с class1 a template class. Это работает в g ​​cc, но не в Visual Studio 2019. Я использую модифицированную версию примера консоли Hello World в Visual Studio.

# include <iostream>

// begin ns1
namespace ns1 {
    // begin class1
    template <class Type> class class1 {
    private:
       Type value_;
    public:
       class1(Type value ) : value_(value)
       { }
       Type Value(void) const
       {   return value_; }
    }; // end class1
    // forward declaration or operator
    template <class Type> class1<Type> operator * 
    (const class1<Type>& left, const class1<Type>& right);
    // begin ns1
    namespace ns2 {
        // begin class2
        class class2 {
            friend ns1::class1<int> ns1::operator * <int> 
            (const ns1::class1<int>& left, const ns1::class1<int>& right);
        private:
            int value_;
        public:
            class2( int value ) : value_(value)
            { }
            int Value(void) const
            {   return value_; }
        }; // end class2
    } // end ns2
    template <class Type> class1<Type> operator *
    (const class1<Type>& left, const class1<Type> &right)
    {   ns2::class2 one(1);
    // use private access to value_ to make sure friend statement working
    return class1<Type>( one.value_ * left.Value() * right.Value() );
    }
} // end ns1

// begin main
int main(void)
{   ns1::class1<int> two(2), three(3);
    ns1::class1<int> six = two * three;
    std::cout << "six.Value() = " << six.Value() << "\n";
    return 0;
} // end main

Ответы [ 2 ]

0 голосов
/ 03 сентября 2020

Это:

# include <iostream>

namespace ns1 {
  template <class Type> class class1 {
    private:
      Type value_;
    public:
      class1(Type value ) : value_(value) { }
      Type Value(void) const { return value_; }
  };

  // forward declaration or operator
  template <class Type> class1<Type> operator * (const class1<Type>& left, const class1<Type>& right);

  namespace ns2 {
    class class2 {
      friend class1<int> operator * <int> (const class1<int>& left, const class1<int>& right);
      private:
        int value_;
      public:
        class2( int value ) : value_(value) { }
        int Value(void) const { return value_; }
    };
  }
    
  template <class Type> class1<Type> operator * (const class1<Type>& left, const class1<Type> &right) {
    ns2::class2 one(1);
    // use private access to value_ to make sure friend statement working
    return class1<Type>( one.value_ * left.Value() * right.Value() );
  }
}

int main(void) {
  ns1::class1<int> two(2), three(3);
  ns1::class1<int> six = two * three;
  std::cout << "six.Value() = " << six.Value() << "\n";
  return 0;
}

работает с g ++:

gcc -std=c++14 -Wall -pedantic -c b.cpp

и прерывается с Visual Studio 2019 версии 19.27 с error C2063: 'ns1::operator *': non è una funzione в объявлении friend.

Это различие исправляет:

<       friend class1<int> operator * <int> (const class1<int>& left, const class1<int>& right);
---
>       template <class Type> friend class1<Type> ns1::operator * (const class1<Type>& left, const class1<Type>& right);

Примечание: это происходит только с operator *, если я попробую operator +, нет необходимости использовать шаблон generi c ... странно!

0 голосов
/ 02 сентября 2020

Воспроизводится здесь:

cl a.cpp
Microsoft (R) C/C++ Optimizing Compiler versione 19.27.29111 per x64
Copyright (C) Microsoft Corporation. Tutti i diritti  sono riservati.

a.cpp
a.cpp(22): error C2063: 'ns1::operator *': non è una funzione

может быть, он работает на Godbolt, потому что у него 19,24?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...