首页 > 解决方案 > Visual Studio 2019 C++ 无法识别模板好友

问题描述

我有一个示例 C++ 程序(包括在下面),它可以在 Visual Studio 2019 中使用普通版本的 class1 但不能使用模板版本的 class1。两个版本都在 gcc 中工作。我从 Visual Studio 2019 收到的错误消息是:

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

我的问题是 Visual Studio 如何期望我在下面的示例中为模板案例声明朋友运算符?

带有class1 的代码版本是一个计划类。这适用于 gcc 和 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 模板类的代码版本。这适用于 gcc,但不适用于 Visual Studio 2019。我在 Visual Studio 中使用 Hello World 控制台示例的修改版本。

# 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

标签: c++templatesvisual-studio-2019operator-keywordfriend

解决方案


这个:

# 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

error C2063: 'ns1::operator *': non è una funzione并在声明中与 Visual Studio 2019 版本 19.27 中断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 +没有必要使用通用模板......奇怪!


推荐阅读