我目前正在尝试用C ++学习模板,但我无法理解当前的错误。
我试图根据书中的代码示例编写一个序列类。我一直反复得到这个错误。
我需要以模块方式编写此模板。功能工作,但我找不到错误的来源。我试过更改.cpp文件的名称没有成功。
这段代码几乎与我在书中发现并运行的代码完全相同。
这是标题和实现文件的代码。
#ifndef SEQUENCE_H
#define SEQUENCE_H
#include <cstdlib> // provides size_t
namespace CS3358_FA17_A04_sequenceOfNum
{
template <class Item>
class sequence
{
public:
// TYPEDEFS and MEMBER CONSTANTS
typedef Item value_type;
typedef size_t size_type;
static const size_type CAPACITY = 10;
// CONSTRUCTOR
sequence();
// MODIFICATION MEMBER FUNCTIONS
void start();
void end();
void advance();
void move_back();
void add(const Item& entry);
void remove_current();
// CONSTANT MEMBER FUNCTIONS
size_type size() const;
bool is_item() const;
Item current() const;
private:
Item data[CAPACITY];
size_type used;
size_type current_index;
};
}
#include "sequence.hpp"
.HPP文件:
namespace CS3358_FA17_A04_sequenceOfNum
{
template <class Item>
sequence<Item>::sequence() : used(0), current_index(0) { }
template <class Item>
void sequence<Item>::start() { current_index = 0; }
template <class Item>
void sequence<Item>::end()
{
current_index = (used > 0) ? used - 1 : 0;
}
template <class Item>
void sequence<Item>::advance()
{
assert( is_item() );
++current_index;
}
template <class Item>
void sequence<Item>::move_back()
{
assert( is_item() );
if (current_index == 0)
current_index = used;
else
--current_index;
}
template <class Item>
void sequence<Item>::add(const Item& entry)
{
assert( size() < CAPACITY );
size_type i;
if ( ! is_item() )
{
if (used > 0)
for (i = used; i >= 1; --i)
data[i] = data[i - 1];
data[0] = entry;
current_index = 0;
}
else
{
++current_index;
for (i = used; i > current_index; --i)
data[i] = data[i - 1];
data[current_index] = entry;
}
++used;
}
template <class Item>
void sequence<Item>::remove_current()
{
assert( is_item() );
size_type i;
for (i = current_index + 1; i < used; ++i)
data[i - 1] = data[i];
--used;
}
template <class Item>
typename sequence<Item>::size_type sequence<Item>::size() const { return used;}
template <class Item>
bool sequence<Item>::is_item() const { return (current_index < used); }
template <class Item>
typename sequence<Item>::Item sequence<Item>::current() const
{
assert( is_item() );
return data[current_index];
}
}
错误是:
序列没有命名类型 - &gt;这发生在每个函数
中'&lt;'之前的预期初始化程序每个地方都使用模板说明符。
之前我编写过很多模板,但由于编译器和链接器问题,我总是在同一个文件中定义和实现。
非常感谢任何帮助,这里有一个完整的错误列表及其行。
g++ -Wall -ansi -pedantic -c sequence.cpp
sequence.cpp:48:4: error: ‘sequence’ does not name a type
sequence<Item>::sequence() : used(0), current_index(0) { }
^
sequence.cpp:51:17: error: expected initializer before ‘<’ token
void sequence<Item>::start() { current_index = 0; }
^
sequence.cpp:54:17: error: expected initializer before ‘<’ token
void sequence<Item>::end()
^
sequence.cpp:60:17: error: expected initializer before ‘<’ token
void sequence<Item>::advance()
^
sequence.cpp:67:17: error: expected initializer before ‘<’ token
void sequence<Item>::move_back()
^
sequence.cpp:77:17: error: expected initializer before ‘<’ token
void sequence<Item>::add(const Item& entry)
^
sequence.cpp:102:17: error: expected initializer before ‘<’ token
void sequence<Item>::remove_current()
^
sequence.cpp:114:4: error: ‘sequence’ does not name a type
sequence<Item>::size_type sequence<Item>::size() const { return used; }
^
sequence.cpp:117:17: error: expected initializer before ‘<’ token
bool sequence<Item>::is_item() const { return (current_index < used); }
^
sequence.cpp:120:4: error: ‘sequence’ does not name a type
sequence<Item>::Item sequence<Item>::current() const
这是Makefile,还编辑了我在文件扩展名中的更改。
a4s1: sequence.o sequenceTest.o
g++ sequence.o sequenceTest.o -o a4s1
sequence.o: sequence.hpp sequence.h
g++ -Wall -ansi -pedantic -c sequence.hpp
sequenceTest.o: sequenceTest.cpp sequence.hpp sequence.h
g++ -Wall -ansi -pedantic -c sequenceTest.cpp
test:
./a4s1 auto < a4test.in > a4test.out
clean:
@rm -rf sequence.o sequenceTest.o
cleanall:
@rm -rf sequence.o sequenceTest.o a4s1
答案 0 :(得分:1)
&#34; 在头文件中包含实现&#34;并不意味着#include <sequence.cpp>
,这意味着实际拥有sequence.h
中的所有内容。
可能的解决方案是:
#include <sequence.h>
位于顶部并使用explicit template instantiation。答案 1 :(得分:0)
必须在他们使用的每个编译单元中定义模板,请参阅here。这通常意味着它们的实现必须放在头文件中。如果你想将实现放在一个单独的文件中,你可以创建一个“实现文件”并将它包含在标题的末尾。这似乎是你教授推荐的策略。
但是,您的构建系统可能不会将实现文件视为单独的编译单元。它应该以.imp或.hpp或其他内容结尾但不是.cpp。