c++ - 如何检查特定模板参数是否相同

标签 c++ templates c++20 c++-concepts

我有一个包含三个模板参数的类:

template<typename A, typename B, typename C>
class Unit;

然后我有一个代表这个类及其所有特化的概念:

template <typename T>
struct is_unit : std::false_type {};

template<typename A, typename B, typename C>
struct is_unit<Unit<A, B, C>> : std::true_type {};

template <typename T>
constexpr bool is_unit_v = is_unit<T>::value;

template <typename T>
concept Unit_T = is_unit_v<T>;

在 Unit 类的定义中,我想要一个返回 Unit 的函数,该 Unit 与调用该函数的函数具有不同的特化。我希望用户提供所需的返回类型。到目前为止我有这个工作:

template<typename A, typename B, typename C>
class Unit {
public:
    // Other member stuff...

    template<Unit_T U>
    U as() { return U(*this); }
}

Unit<MyType, long double, MyOtherType> unit;
// Do stuff to unit.
auto unit2 = unit.as<Unit<MyType, long int, AnotherType>();

一切都按预期工作。但是,还有一个要求,我不知道如何实现。所需类型的第一个模板参数必须与调用它的类型的第一个模板参数相匹配。所以这个:

Unit<MyType, long double, MyOtherType> unit;
// Do stuff to unit.
auto unit2 = unit.as<Unit<YetAnotherType, long int, AnotherType>();

不应编译。

我认为正确的做法应该是这样的:

template<typename A, typename B, typename C>
class Unit {
public:
    // Other member stuff...

    template<Unit_T U>
    requires std::is_same_v<U<D>, D>
    // or maybe std::is_same_V<U::D, D> ?
    U as() { return U(*this); }
}

但这行不通。而且,据我所知,即使这是要求模板参数为正确类型的正确方法,我也无法进一步限制概念。

我尝试为具有特定第一个模板参数的单元编写另一个概念:

template<typename U, typename D>
concept UnitFirstType = is_unit_v<U> && std::is_same_v<U<D> /* or U::D */, D>;

但这行不通。

问题似乎在于我如何使用 std::is_same_v。我只是不知道如何将它与模板参数一起使用。

那么实现这一目标的正确方法是什么:

Unit<MyType, long double, MyOtherType> unit;
auto unit2 = unit.as<Unit<MyType, long int, AnotherType>(); // will compile
// auto unit3 = unit.as<Unit<YetAnotherType, long int, AnotherType>(); // should not compile

最佳答案

这可能是你想要的

template<typename A, typename B, typename C>
class Unit;

template<typename U, typename A>
constexpr bool unit_first_type = false;

template<typename A, typename B, typename C>
constexpr bool unit_first_type<Unit<A, B, C>, A> = true;

template<typename U, typename A>
concept UnitFirstType = unit_first_type<U, A>;

template<typename A, typename B, typename C>
class Unit {
 public:
  // Other member stuff...
  template<UnitFirstType<A> U>
  U as();
};

Demo

关于c++ - 如何检查特定模板参数是否相同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72419746/

相关文章:

c++ - #pragma 弃用基于签名的函数?

c++ - C++ 概念的通配符为 "accepting anything for this template argument"

c++ - #include 模板递归

c++ - 什么是 "span",我应该什么时候使用?

c++:PThread 调度与 Windows 线程

c++ - 将变量添加到已在 C++ 中声明的数组?

c++ - 使用 cmake 构建 QTCharts

android - C++ 模板类显式实例化因 GCC/NDK 而失败

c++ - 重写的比较运算符和表达式模板

c++ - 如何使用折叠表达式调用成员函数链