C++模板功能的明确实例化导致“无定义”错误。
当试图编译文件时,发生此错误时发生:
错误,
Logging.h: In instantiation of 'void Sudoku::printBoardWithCandidates(const Sudoku::Board<BASE>&) [with int BASE = 3]':
Logging.h:10:64: required from here
Logging.h:10:64: error: explicit instantiation of 'void Sudoku::printBoardWithCandidates(const Sudoku::Board<BASE>&) [with int BASE = 3]' but no definition available [-fpermissive]
template void printBoardWithCandidates<3>(const Board<3>& b);
^
因为我在C ++方面不是很有经验,所以我看不出任何可能导致此问题的原因。由于该定义存在于.cpp文件中,因此我认为没有任何理由不编译。有人不介意向我解释吗?
.h文件
#pragma once
#include "Board.h"
namespace Sudoku
{
template<int BASE>
void printBoardWithCandidates(const Board<BASE> &b);
template void printBoardWithCandidates<2>(const Board<2>&);
template void printBoardWithCandidates<3>(const Board<3>&);
template void printBoardWithCandidates<4>(const Board<4>&);
}
.cpp文件
#include "Logging.h"
#include <iostream>
template<int BASE>
void Sudoku::printBoardWithCandidates(const Board<BASE> &board)
{
// definition...
}
编辑: 在整个程序中,我已经使用了多次的类似实施。例如 board.h
#pragma once
#include <vector>
#include <cstring>
#include "stdint.h"
namespace Sudoku
{
struct Cell
{
int RowInd;
int ColInd;
int BoxInd;
friend bool operator==(const Cell& cell1, const Cell& cell2);
};
bool operator==(const Cell& cell1, const Cell& cell2);
template<int BASE>
class Board
{
public:
static constexpr int WIDTH = BASE * BASE;
static constexpr int CELL_COUNT = WIDTH * WIDTH;
static constexpr uint16_t CELL_COMPLETELY_OCCUPIED = 65535 >> (sizeof(uint16_t) * 8 - WIDTH);
private:
const int EMPTY_VALUE;
uint16_t rowOccupants[WIDTH] = {0};
uint16_t colOccupants[WIDTH] = {0};
uint16_t boxOccupants[WIDTH] = {0};
int* solution;
void Init();
void Eliminate(Cell& cell, uint16_t value);
public:
std::vector<Cell> EmptyCells;
Board(const int* puzzle, int* solution, int emptyValue = -1);
void SetValue(Cell cell, uint16_t value);
void SetValue(Cell cell, int value);
int* GetSolution() const;
inline uint16_t GetOccupants(Cell cell) const
{
return rowOccupants[cell.RowInd] | colOccupants[cell.ColInd] | boxOccupants[cell.BoxInd];
}
};
template class Board<2>;
template class Board<3>;
template class Board<4>;
} // namespace Sudoku
When trying to compile the files bellow this error occurs:
The error
Logging.h: In instantiation of 'void Sudoku::printBoardWithCandidates(const Sudoku::Board<BASE>&) [with int BASE = 3]':
Logging.h:10:64: required from here
Logging.h:10:64: error: explicit instantiation of 'void Sudoku::printBoardWithCandidates(const Sudoku::Board<BASE>&) [with int BASE = 3]' but no definition available [-fpermissive]
template void printBoardWithCandidates<3>(const Board<3>& b);
^
As I am not very experienced in C++ I don't see any possible cause for this problem. Since the definition is present in .cpp file I dont see any reason not to compile. Wouldn't someone mind explaing that to me, please?
.h file
#pragma once
#include "Board.h"
namespace Sudoku
{
template<int BASE>
void printBoardWithCandidates(const Board<BASE> &b);
template void printBoardWithCandidates<2>(const Board<2>&);
template void printBoardWithCandidates<3>(const Board<3>&);
template void printBoardWithCandidates<4>(const Board<4>&);
}
.cpp file
#include "Logging.h"
#include <iostream>
template<int BASE>
void Sudoku::printBoardWithCandidates(const Board<BASE> &board)
{
// definition...
}
Edit:
Similar implementatiin I have employed several times throughout the program. For example
Board.h
#pragma once
#include <vector>
#include <cstring>
#include "stdint.h"
namespace Sudoku
{
struct Cell
{
int RowInd;
int ColInd;
int BoxInd;
friend bool operator==(const Cell& cell1, const Cell& cell2);
};
bool operator==(const Cell& cell1, const Cell& cell2);
template<int BASE>
class Board
{
public:
static constexpr int WIDTH = BASE * BASE;
static constexpr int CELL_COUNT = WIDTH * WIDTH;
static constexpr uint16_t CELL_COMPLETELY_OCCUPIED = 65535 >> (sizeof(uint16_t) * 8 - WIDTH);
private:
const int EMPTY_VALUE;
uint16_t rowOccupants[WIDTH] = {0};
uint16_t colOccupants[WIDTH] = {0};
uint16_t boxOccupants[WIDTH] = {0};
int* solution;
void Init();
void Eliminate(Cell& cell, uint16_t value);
public:
std::vector<Cell> EmptyCells;
Board(const int* puzzle, int* solution, int emptyValue = -1);
void SetValue(Cell cell, uint16_t value);
void SetValue(Cell cell, int value);
int* GetSolution() const;
inline uint16_t GetOccupants(Cell cell) const
{
return rowOccupants[cell.RowInd] | colOccupants[cell.ColInd] | boxOccupants[cell.BoxInd];
}
};
template class Board<2>;
template class Board<3>;
template class Board<4>;
} // namespace Sudoku
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题是,在您提供
3
显式模板Instantiation 的标题文件中的点, definiti >不可用的是相应的成员函数模板printboardWithCandidates
。因此,编译器无法生成这些实例化的定义,并给出了上述错误说:解决此问题的方法有两种,如下所示。还请注意,我使用了一个空结构
板
,因为您提供的board
类非常大(长度),如果在这里粘贴了2次,将占用很多空间。这个概念是相同的。方法1
在提供3个显式模板实例之前,在标题中提供了成员函数模板
printboardwithCandidates
,如下所示:header.h
board.h
main.cpp
工作demo
方法2
在这里我们提供了成员的定义函数模板以及源文件中的3个显式模板实例化。在标题文件中,我们仅提供成员函数模板的声明,并且标题文件中没有提供明确的模板实例化。
header.h
board.h
source.cpp
main.cpp
The problem is that at the point inside the header file where you have provided the
3
explicit template instantiation, the definition of the corresponding member function templateprintBoardWithCandidates
is not available. Thus, the compiler cannot generate the definition for these instantiations and gives the mentioned error saying:There are two ways to solve this as shown below. Note also that i have used an empty struct
Board
since theBoard
class you provided is very big(in length) and will take a lot of space if pasted here 2 times. The concept is the same though.Method 1
Provide the definition for the member function template
printBoardWithCandidates
in the header before providing the 3 explicit template instantiations as shown below:header.h
Board.h
main.cpp
Working demo
Method 2
Here we provide the definition of the member function template as well as the 3 explicit template instantiations in the source file. In the header file we only provide the declaration for the member function template and no explicit template instantiation are provided in the header file.
header.h
Board.h
source.cpp
main.cpp
Working demo