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

时间:2013-05-21 18:15:31

标签: c++

我编译了下面的代码并使用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

包含主要功能的正文文件:

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

int main(int argc, char* argv[])
{
    A<int> a;
    B<int> b(a);

    return 0;
}

英特尔编译器返回的错误是:

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

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

//<#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;
}

1 个答案:

答案 0 :(得分:1)

B移除A.h的转发声明,并颠倒包含的顺序。

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

在声明个别成员函数friend之前,您不能创建它们。 因此,B的ctor(以及B)需要在friend中将其声明为A之前显示。但是,B只能使用A的前誓声明,因为它只使用referenceA

因此你需要颠倒包含的顺序。