当尝试编译下面的文件时,出现这个错误:
误差
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
问题是在头文件中提供3
显式模板实例化的地方,定义对应的成员函数模板printBoardWithCandidates
不可用。因此,编译器不能为这些实例化生成定义,并给出上述错误:
error: explicit instantiation of 'void Sudoku::printBoardWithCandidates(const Sudoku::Board<BASE>&) [with int BASE = 3]'
but no definition available [-fpermissive]
^^^^^^^^^^^^^^^^^^^^^^^^^^^
有两种方法可以解决这个问题,如下所示。还请注意,我已经使用了一个空结构体Board
,因为您提供的Board
类非常大(长度),如果粘贴在这里2次,将占用大量空间。但概念是一样的。
方法1
在头文件中提供成员函数模板printBoardWithCandidates
的定义,然后提供3个显式的模板实例化,如下所示:
header.h
#pragma once
#include "Board.h"
namespace Sudoku
{
template<int BASE>
void printBoardWithCandidates(const Board<BASE> &b)
{
//note this is a definition
}
//explicit template instantiation declaration
extern template void printBoardWithCandidates<2>(const Board<2>&);
extern template void printBoardWithCandidates<3>(const Board<3>&);
extern template void printBoardWithCandidates<4>(const Board<4>&);
}
Board.h
#pragma once
template<int>
struct Board
{
};
main.cpp
#include <iostream>
#include "header.h"
//explicit template instantiation definition
template void Sudoku::printBoardWithCandidates<2>(const Board<2>&);
template void Sudoku::printBoardWithCandidates<3>(const Board<3>&);
template void Sudoku::printBoardWithCandidates<4>(const Board<4>&);
int main()
{
return 0;
}
演示工作
方法2
这里我们提供了成员函数模板的定义以及源文件中的3个显式模板实例化。在头文件中,我们只提供了成员函数模板的声明,而没有在头文件中提供显式的模板实例化。
header.h
#pragma once
#include "Board.h"
namespace Sudoku
{
//this is a declaration not a definition
template<int BASE>
void printBoardWithCandidates(const Board<BASE> &b);
//no explicit template instantiation here since we have provided only the declaration above and not the definition
}
Board.h
#pragma once
template<int>
struct Board
{
};
source.cpp
#include "header.h"
//provide the definition here
template<int BASE>
void Sudoku::printBoardWithCandidates(const Board<BASE> &board)
{
// definition...
}
template void Sudoku::printBoardWithCandidates<2>(const Board<2>&);
template void Sudoku::printBoardWithCandidates<3>(const Board<3>&);
template void Sudoku::printBoardWithCandidates<4>(const Board<4>&);
main.cpp
#include <iostream>
#include "header.h"
int main()
{
return 0;
}
演示工作