模板类构造函数作为其他模板类的朋友

Template Class Constructor as Friend of Other Template Class

本文关键字:朋友 其他 构造函数      更新时间:2023-10-16

我已经编译了下面的代码,并在Microsoft Visual Studio 2008的编译器中成功运行了它。然而,我需要在生产中使用的编译器(由于项目限制)是Intel c++编译器11.1.065。

所以,我的问题是:以下代码中语法的某些部分是否不正确(和visual studio编译器只是与它一起工作),或者我使用的英特尔编译器的版本是否缺乏支持?如果是这样,有没有人愿意提供11.1.065版本的英特尔编译器可以理解的语法?提前感谢!

头文件A.h:

#ifndef A_H
#define A_H
#include "B.h"
//forward declarations
template <typename T> class B;
// I tried adding the following line (even though it is
//    not needed by the visual studio compiler:
//template <typename T> B<T>::B(A<T> const&);
template <typename T>
class A
{
private:
    int m_var;
public:
    A() : m_var(1) {}
    friend B<T>::B(A<T> const& x);
};
#endif //A_H

头文件B.h:

#ifndef B_H
#define B_H
#include "A.h"
template <typename T> class A;
template <typename T>
class B
{
private:
    int m_var;
public:
    B(A<T> const& x)
        : m_var(x.m_var)
    {}
};
#endif //B_H

带有Main函数的主体文件:

#include "B.h"
#include "A.h"
int main(int argc, char* argv[])
{
    A<int> a;
    B<int> b(a);
    return 0;
}

Intel编译器返回的错误是:

.A.h(16): error: expected a ")"
      friend B<T>::B(A<T> const& x);
                          ^

编辑:由于这是否是由多次包含引起的关注太多,因此上面的代码扩展为以下代码,这表明多次包含不应该影响代码:

//<#include "B.h" expanded>
#ifndef B_H
#define B_H
//<#include "A.h" expanded>
#ifndef A_H
#define A_H
//<#include "B.h" expanded>
//   Because B_H is defined, B.h's contents are not expanded
//</#include "B.h" expanded>
//forward declarations
template <typename T> class B;
// I tried adding the following line (even though it is
//    not needed by the visual studio compiler:
//template <typename T> B<T>::B(A<T> const&);
template <typename T>
class A
{
private:
    int m_var;
public:
    A() : m_var(1) {}
    friend B<T>::B(A<T> const& x);
};
#endif //A_H
//</#include "A.h" expanded>
template <typename T> class A;
template <typename T>
class B
{
private:
    int m_var;
public:
    B(A<T> const& x)
        : m_var(x.m_var)
    {}
};
#endif //B_H
//</#include "B.h" expanded>
//<#include "A.h" expanded>
//   Because A_H is defined, A.h's contents are not expanded
//</#include "A.h" expanded>
int main(int argc, char* argv[])
{
    A<int> a;
    B<int> b(a);
    return 0;
}

B的正向声明从A.h中移除,并反转include的顺序。

#include "B.h"
#include "A.h".

你不能让单独的成员函数friend s,直到它们被声明。因此,在将A声明为friend之前,B的ctor(以及B)需要是可见的。然而,B可以只使用A的fwd声明,因为它只使用referenceA

因此您需要颠倒include的顺序。