这段代码不会用MSVC编译,它包含C++ 20 spirit中的模板专门化。有人能帮忙吗?代码包含模板专门化,并使用模块,但它将无法工作。
//Grid.cppm
export module grid;
export import :main;
export import :string;
//GridMain.cppm
module;
#include <cstddef>
export module grid:main;
import <stdexcept>;
import <vector>;
import <optional>;
import <utility>;
import <format>;
export
template <typename T>
class Grid
{
public:
explicit Grid(size_t width = DefaultWidth, size_t height = DefaultHeight);
virtual ~Grid() = default;
// Explicitly default a copy constructor and copy assignment operator.
Grid(const Grid& src) = default;
Grid& operator=(const Grid& rhs) = default;
// Explicitly default a move constructor and move assignment operator.
Grid(Grid&& src) = default;
Grid& operator=(Grid&& rhs) = default;
std::optional<T>& at(size_t x, size_t y);
const std::optional<T>& at(size_t x, size_t y) const;
size_t getHeight() const { return m_height; }
size_t getWidth() const { return m_width; }
static const size_t DefaultWidth{ 10 };
static const size_t DefaultHeight{ 10 };
private:
void verifyCoordinate(size_t x, size_t y) const;
std::vector<std::vector<std::optional<T>>> m_cells;
size_t m_width{ 0 }, m_height{ 0 };
};
template <typename T>
Grid<T>::Grid(size_t width, size_t height)
: m_width{ width }
, m_height{ height }
{
m_cells.resize(m_width);
for (auto& column : m_cells) {
column.resize(m_height);
}
}
template <typename T>
void Grid<T>::verifyCoordinate(size_t x, size_t y) const
{
if (x >= m_width) {
throw std::out_of_range{ std::format("{} must be less than {}.", x, m_width) };
}
if (y >= m_height) {
throw std::out_of_range{ std::format("{} must be less than {}.", y, m_height) };
}
}
template <typename T>
const std::optional<T>& Grid<T>::at(size_t x, size_t y) const
{
verifyCoordinate(x, y);
return m_cells[x][y];
}
template <typename T>
std::optional<T>& Grid<T>::at(size_t x, size_t y)
{
return const_cast<std::optional<T>&>(std::as_const(*this).at(x, y));
}
//GridString.cppm
module;
#include <cstddef>
export module grid:string;
import <stdexcept>;
import <vector>;
import <optional>;
import <utility>;
import <string>;
import <format>;
// When the template specialization is used, the original template must be
// visible too.
import :main;
export
template <>
class Grid<const char*>
{
public:
explicit Grid(size_t width = DefaultWidth, size_t height = DefaultHeight);
virtual ~Grid() = default;
// Explicitly default a copy constructor and copy assignment operator.
Grid(const Grid& src) = default;
Grid& operator=(const Grid& rhs) = default;
// Explicitly default a move constructor and move assignment operator.
Grid(Grid&& src) = default;
Grid& operator=(Grid&& rhs) = default;
std::optional<std::string>& at(size_t x, size_t y);
const std::optional<std::string>& at(size_t x, size_t y) const;
size_t getHeight() const { return m_height; }
size_t getWidth() const { return m_width; }
static const size_t DefaultWidth{ 10 };
static const size_t DefaultHeight{ 10 };
private:
void verifyCoordinate(size_t x, size_t y) const;
std::vector<std::vector<std::optional<std::string>>> m_cells;
size_t m_width{ 0 }, m_height{ 0 };
};
Grid<const char*>::Grid(size_t width, size_t height)
: m_width{ width }
, m_height{ height }
{
m_cells.resize(m_width);
for (auto& column : m_cells) {
column.resize(m_height);
}
}
void Grid<const char*>::verifyCoordinate(size_t x, size_t y) const
{
if (x >= m_width) {
throw std::out_of_range{ std::format("{} must be less than {}.", x, m_width) };
}
if (y >= m_height) {
throw std::out_of_range{ std::format("{} must be less than {}.", y, m_height) };
}
}
const std::optional<std::string>& Grid<const char*>::at(size_t x, size_t y) const
{
verifyCoordinate(x, y);
return m_cells[x][y];
}
std::optional<std::string>& Grid<const char*>::at(size_t x, size_t y)
{
return const_cast<std::optional<std::string>&>(std::as_const(*this).at(x, y));
}
//GridTest.cpp
import <iostream>;
import <string>;
import grid;
using namespace std;
int main()
{
Grid<int> myIntGrid; // Uses original Grid template.
Grid<const char*> stringGrid1{ 2, 2 }; // Uses const char* specialization.
const char* dummy{ "dummy" };
stringGrid1.at(0, 0) = "hello";
stringGrid1.at(0, 1) = dummy;
stringGrid1.at(1, 0) = dummy;
stringGrid1.at(1, 1) = "there";
Grid<const char*> stringGrid2{ stringGrid1 };
cout << stringGrid1.at(0, 1).value_or("") << endl;
cout << stringGrid2.at(0, 1).value_or("") << endl;
}
代码包含网格结构,它执行专门化,以获得工作网格和模块cpp中的测试。
1条答案
按热度按时间wbgh16ku1#
我使用选项编译作为内部分区,而不是接口
使用/interface而不是内部分区。您可能误解了/接口。https://learn.microsoft.com/en-us/cpp/build/reference/interface?view=msvc-170
当模块接口的扩展名不同于. ixx时,请使用此开关。
在下面的示例中,模块接口的扩展名为.cppm而不是.ixx,因此/interface开关用于将其编译为模块接口: