我正在尝试学习需求表达式,作为熟悉概念机制的垫脚石。我能想到的最简单的方法是通过用
static_assert
表达式替换任何模板中的所有 requires
表达式来轻松使用它。
有点难以理解的是
std::is_base_of_v<>
和 std::derived_from<>
之间的区别。
以下
requires
和 static_assert
表达式是否等效,即做同样的事情?如果没有,那又会怎样呢?我的意图是要求在删除任何可能的引用/cv/指针装饰后,GameType
和GameBase
是彼此派生的:
class GameBase {
//...
};
//...
#include <concepts>
#include <string>
#include <type_traits>
template<typename GameType>
requires(std::derived_from<GameType, GameBase>)
class Engine {
public:
static_assert(std::is_base_of_v<std::remove_cvref_t<std::remove_pointer_t<GameBase>>, std::remove_cvref_t<std::remove_pointer_t<GameType>>>, "GameType template parameter is not derived from GameBase.");
static void Initialize(const std::string& title, const std::string& cmdString) noexcept;
static void Run() noexcept;
static void Shutdown() noexcept;
static const bool Available() noexcept;
private:
static inline bool m_initCalled{false};
static inline bool m_shutdownCalled{false};
};
这是一个回答您问题的示例。
#include <type_traits>
#include <concepts>
template <typename T>
struct foo;
template <typename T>
requires(std::same_as<T, int>)
struct foo<T>{};
template <typename T>
requires(std::same_as<T, double>)
struct foo<T>{};
template <typename T>
struct bar;
/// error, static_assert cannot be used as specilization
/*
template <typename T>
struct bar<T>{
static_assert(std::is_same_v<int, T>);
};
template <typename T>
struct bar<T>{
static_assert(std::is_same_v<double, T>);
};
*/