Visual Studio 2019 C++无法识别模板好友



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

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

我的问题是VisualStudio希望我如何在下面的示例中声明模板事例的友元运算符?

类1为计划类的代码的版本。这项工作在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

类1为模板类的代码版本。这在gcc上有效,但在Visual Studio 2019中无效。我使用的是VisualStudio中HelloWorld控制台示例的修改版本。

# 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

这:

# 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

并且在friend声明处与具有error C2063: 'ns1::operator *': non è una funzione的Visual Studio 2019 19.27版本决裂。

这个差异修复了它:

<       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 +,就不需要使用通用模板。。。奇怪的

我把它归结为一个简单的复制案例。

namespace Some
{
// Forward declarations.
template <typename T> class Stuff;
template <typename T> class Thing;
template <typename T> Stuff<T> operator*( const Stuff<T>& lhs, const Thing<T>& rhs );
template <typename T> Thing<T> operator*( const T& s, const Thing<T>& rhs );
// Class definition.
template <typename T>
class Thing
{
#if 0
template<typename U> friend typename std::enable_if<std::is_same<T, U>::value, Stuff<U> >::type operator*(const Stuff<U>& lhs, const Thing<U>& rhs);
template<typename U> friend typename std::enable_if<std::is_same<T, U>::value, Thing<U> >::type operator*(const U& s, const Thing<U>& rhs);
#else
friend Stuff<T> Some::operator* <T>( const Stuff<T>& lhs, const Thing<T>& rhs );
friend Thing<T> Some::operator* <T>( const T& s, const Thing<T>& rhs );
#endif
};
} //namespace Some
int
main(int argc, char** argv)
{
Some::Thing<float> mat;
return 0;
}

这在VS2010、VS2017、gcc/MinGW和clang/MinGW中构建良好,但VS2019会生成虚假错误。

我已将此作为错误提交给Microsoft。

顺便说一句,注释掉的版本也适用于所有编译器,并确保friend函数只为同一类型定义,但显然要冗长得多。

此处可再现:

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?

相关内容

  • 没有找到相关文章

最新更新