c++ - C++ 模块导出类
问题描述
// random.ixx
export {
struct random_trait;
class engine;
}
struct random_trait
{
using bits64_type = std::uint64_t;
using bits32_type = std::uint32_t;
using size_type = std::size_t;
constexpr static bits64_type default_seed = static_cast<bits64_type>(1234567890);
template <std::unsigned_integral T, size_type N>
struct type_generator
{
using result_type = std::conditional_t<
std::is_same_v<T, bits64_type> or
std::numeric_limits<T>::digits == std::numeric_limits<bits64_type>::digits,
bits64_type,
std::conditional_t<
std::is_same_v<T, bits32_type> or
std::numeric_limits<T>::digits == std::numeric_limits<bits32_type>::digits,
bits32_type,
nullptr_t
>
>;
using state_type = std::array<result_type, N>;
static_assert(!std::is_same_v<result_type, nullptr_t>, "not supported type");
};
template <size_type N>
using bits64_generator = type_generator<bits64_type, N>;
template <size_type N>
using bits32_generator = type_generator<bits32_type, N>;
};
template <typename T>
concept generated_type = requires
{
typename T::result_type;
typename T::state_type;
};
template <generated_type T>
struct seed_generator final
{
using result_type = typename T::result_type;
using state_type = typename T::state_type;
constexpr result_type operator()() noexcept
{
...
}
constexpr state_type generate_seeds() noexcept
{
...
}
result_type seed_;
};
template <generated_type T>
class engine_base
{
using engine_base_reference = engine_base<T>bitand;
using const_engine_base_reference = const engine_base<T>bitand;
using engine_base_rreference = engine_base<T>and;
public:
using result_type = typename T::result_type;
using state_type = typename T::state_type;
constexpr static auto bits_of_this = std::numeric_limits<result_type>::digits;
constexpr explicit engine_base(state_type state) noexcept : state_(std::move(state)) {}
constexpr explicit engine_base(result_type seed = random_trait::default_seed) noexcept
: state_(seed_generator<T>{seed}.generate_seeds()) {}
}
class engine64_x4_base : public engine_base<random_trait::bits64_generator<4>>
{
public:
using engine_base::engine_base;
protected:
using engine_base::state_;
}
class engine final : public engine64_x4_base
{
public:
using engine64_x4_base::engine64_x4_base;
};
// test.cpp
engine e{};
// error:
// this overload call is ambiguous, it may be engine64_x4_base(void)
// or
// engine64_x4_base(unsigned __int64) (this is inherited from engine_base)
// unsigned __int64 is engine_base's result_type, so it is engine_base(result_type seed = random_trait::default_seed)
问题是为什么会有歧义?或者为什么有默认构造(engine64_x4_base(void))?
然后我试着把所有的代码放到hpp文件中,所有的问题都解决了,也按预期运行了(虽然IDE有个错误说找不到引擎的operator()())。
这是一个模块问题,但我不知道如何解决它。我还应该导出基类吗?
因为我删除了一些不影响问题的函数(这些类的一些成员函数),这使得继承关系看起来很有趣,请不要介意:)
==================================================== ===
终于找到了导出engine_base的解决方案(但是继承链中间的engine64_x4_base不需要导出)。
一切都按预期工作,但我无法理解,因为 engine_base 需要导出是非常不合理的。
还有一点需要注意的是,如果我给引擎构造一个参数而不导出engine_base(尽量避免无缘无故不给参数造成的歧义),编译器会输出“Internal Compiler Error: When generated a constructor for engine (constexpr 显式引擎(__uint64 种子) noexcept)"
解决方案
推荐阅读
- javascript - 调用函数时,如何在另一行下显示一行?
- parsing - 如何单元和/或集成测试解析器?
- java - 合并两个或多个实体并合并为一个列表
- php - MySQL 特别不响应 PHP
- javascript - 超时函数行为不一致(React)
- java - BlockingQueue 失去了它的引用并抛出 NullPointerException onMessage Jetty WebSocket
- cypress - 赛普拉斯 cy.visit 不加载网站,等待后超时
- python - 如何使用 askcolor 更改按钮的背景颜色
- python - Checkgradient没有解决MATLAB中的优化问题
- java - 将数据从 CSV 文件添加到 Java Derby 数据库在关闭窗口后删除