我有下面的类(它基本上是std :: vector的包装器),其中一个函数返回一个AInteger类型的变量(它基本上是int的包装器)。现在类型AInteger在整个类中被多次使用,但编译器开始在一个非常特定的位置抱怨。当我删除“getSize()”函数时,一切都编译得很好。
相互包容,所以我需要前进声明才能使一切工作。
其中一个问题是AList类是一个模板,因此无法将定义移动到.cpp文件(这通常可以解决问题)。
我做错了什么?
这是班级:
#ifndef ALIST_H
#define ALIST_H
#include <vector>
#include "AInteger.h"
class AInteger;
template<typename VALUE>
class AList {
public:
AList() {
}
AList(const std::vector<VALUE> list) {
value = list;
}
~AList() {
}
operator const std::vector<VALUE>() const {
return value;
}
std::vector<VALUE> toStdVector() const {
return value;
}
VALUE operator [](const AInteger index) const {
return value.at(index);
}
void add(const VALUE value) {
this->value.push_back(value);
}
VALUE get(const AInteger index) const {
return value[index];
}
AInteger getSize() const { // ERROR OCCURS HERE
return value.size();
}
void remove(const AInteger index) {
value.erase(index);
}
private:
std::vector<VALUE> value;
};
#endif
输出:
1>------ Build started: Project: ALibrary, Configuration: Debug Win32 ------
1> ASocket.cpp
1>d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(43): error C2027: use of undefined type 'AInteger'
1> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(8): note: see declaration of 'AInteger'
1> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(53): note: see reference to class template instantiation 'AList<VALUE>' being compiled
1> AInteger.cpp
1>d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(43): error C2027: use of undefined type 'AInteger'
1> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(8): note: see declaration of 'AInteger'
1> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(53): note: see reference to class template instantiation 'AList<VALUE>' being compiled
1> AHttpRequest.cpp
1>d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(43): error C2027: use of undefined type 'AInteger'
1> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(8): note: see declaration of 'AInteger'
1> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(53): note: see reference to class template instantiation 'AList<VALUE>' being compiled
1> ABoolean.cpp
1>d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(43): error C2027: use of undefined type 'AInteger'
1> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(8): note: see declaration of 'AInteger'
1> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(53): note: see reference to class template instantiation 'AList<VALUE>' being compiled
1> Generating Code...
1> Compiling...
1> AString.cpp
1> Generating Code...
2>------ Build started: Project: BitHoarder, Configuration: Debug Win32 ------
2> SystemHandler.cpp
2>d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(43): error C2027: use of undefined type 'AInteger'
2> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(8): note: see declaration of 'AInteger'
2> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(53): note: see reference to class template instantiation 'AList<VALUE>' being compiled
2> Main.cpp
2>d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(43): error C2027: use of undefined type 'AInteger'
2> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(8): note: see declaration of 'AInteger'
2> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(53): note: see reference to class template instantiation 'AList<VALUE>' being compiled
2> Generating Code...
========== Build: 0 succeeded, 2 failed, 0 up-to-date, 0 skipped ==========
如果需要更多代码,请询问,我会提供。
谢谢!
编辑: 这是“AInteger.h”中的代码
#ifndef AINTEGER_H
#define AINTEGER_H
#include "AList.h"
template<typename VALUE>
class AList;
class AInteger {
public:
AInteger();
AInteger(const int);
~AInteger();
operator const int() const;
int toInt() const;
AInteger operator=(const AInteger &);
AInteger & operator++();
AInteger & operator--();
AList<AInteger>splitByNumber(const AInteger &);
private:
int value;
};
#endif
为了让事情更加令人困惑,下面的类做了完全相同的事情并没有产生错误:
#ifndef ADICTIONARY_H
#define ADICTIONARY_H
#include <map>
#include "AInteger.h"
class AInteger;
template<typename KEY, typename VALUE, typename COMPARE = std::less<KEY>>
class ADictionary {
public:
ADictionary() {
}
ADictionary(const std::map<KEY, VALUE, COMPARE> dictionary) {
value = dictionary;
}
~ADictionary() {
}
operator const std::map<KEY, VALUE, COMPARE>() const {
return value;
}
std::map<KEY, VALUE, COMPARE> toStdMap() const {
return value;
}
VALUE operator [](const KEY key) const {
return value.at(key);
}
void add(const KEY key, const VALUE value) {
this->value.insert(std::make_pair(key, value));
}
VALUE get(const KEY key) const {
return value[key];
}
AInteger getSize() const { // No error here
return value.size();
}
void remove(const KEY key) {
value.erase(value.find(key));
}
private:
std::map<KEY, VALUE, COMPARE> value;
};
#endif
答案 0 :(得分:4)
getSize()
的实施必须创建AInteger
的实例。只有在知道AInteger
的完整定义时才可以这样做。您无法创建仅向前声明的类型的实例。
这正是编译器告诉你的:error C2027: use of undefined type 'AInteger'
。它不会忽略前向声明,但会告诉您它不够。
对于#include "AInteger.h"
,您不会显示其内容,但可能存在以下问题:
AInteger
的定义位于命名空间内。答案 1 :(得分:2)
出现问题的答案在Christian Hackl的答案中得到了很好的回答,通常我会把它放在那里,但我无法解释OP如何在评论中正确解决这个问题。
首先修订了AInteger.h
#ifndef AINTEGER_H
#define AINTEGER_H
template<typename VALUE>
class AList;
class AInteger {
public:
AInteger();
AInteger(const int);
~AInteger();
//operator const int() const;
int toInt() const;
AInteger operator=(const AInteger &);
AInteger & operator++();
AInteger & operator--();
std::unique_ptr<AList<AInteger>> splitByNumber(const AInteger &);
void splitByNumber(const AInteger &,
AList<AInteger> &);
private:
int value;
};
#endif
AList.h的包含已经消失。 AList
的前瞻性声明仍然是我提供了两种不同的splitByNumber
方法。选一个。第一个创建并返回a pointer protected by a smart pointer。第二种方法,也是我个人的偏好,引用了调用者创建的AList。
事情对AList
的内部运作一无所知,因为他们关心的是A)它存在,b)它们可以得到一个地址。
在我探索两者时请耐心等待,因为我认为它们都具有教育意义。
除了删除AInteger
的前瞻声明外,Alist.h保持不变。
两个splitByNumber
候选人位于AInteger
的实现文件中,该文件可以安全地包含AInteger.h和AList.h,因此可以同时完全了解两者并且可以完成所有神奇的事物AIntegers
和ALists
可以做到。
std::unique_ptr<AList<AInteger>> AInteger::splitByNumber(const AInteger & integer)
{
std::unique_ptr<AList<AInteger>> listp(new AList<AInteger>());
// do stuff with listp
return listp;
}
void AInteger::splitByNumber(const AInteger & integer,
AList<AInteger> & list)
{
// do stuff with list
}
使用指针版本:
std::unique_ptr<AList<AInteger>> alistp = aitest1.splitByNumber(aitest2);
alistp->add(somenumber);
使用参考版本:
AList<AInteger> alist; // first create an empty AList
aitest1.splitByNumber(aitest2, alist); // pass it into the function
alist.add(somenumber); // use the AList