我如何检查特定的模板参数是相同的
我有一个带有三个模板参数的类:
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>;
在单位类的定义中,我想要一个函数,该函数返回一个具有不同专业化的单元,该功能与该功能所为的函数不同称为。我希望用户提供所需的返回类型。到目前为止,我的工作正常:
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
I have a class with three template parameters:
template<typename A, typename B, typename C>
class Unit;
Then I have a concept representing this class and all its specialization:
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>;
In the definition of the Unit class, I want a function that returns a Unit with a different specialization from the one through which the function is called. I want the user to provide the desired return type. I have this working so far:
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>();
That all works as expected. There's one more requirement, however, that I can't figure out how to implement. The first template parameter of the desired type must match the first template parameter of the type through which it was called. So this:
Unit<MyType, long double, MyOtherType> unit;
// Do stuff to unit.
auto unit2 = unit.as<Unit<YetAnotherType, long int, AnotherType>();
should not compile.
I would think that the correct way to do this would look something like:
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); }
}
But that doesn't work. And, as I understand, even if that was the right way to require a template parameter be the right type, I can't further constrain a concept.
I tried writing another concept for a Unit with a specific first template parameter:
template<typename U, typename D>
concept UnitFirstType = is_unit_v<U> && std::is_same_v<U<D> /* or U::D */, D>;
But that doesn't work.
The problem seems to lie in how I'm using std::is_same_v. I just don't know how to use it with a template parameter.
So what is the proper way to achieve this:
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这可能是您想要的
demo
This is probably what you want
Demo
我想您可以使用良好的老年人(C ++ 20)sfinae。
例如,给定一个自定义类型特征如下所示,
/disable
为()
您可以启用 具有不同的constness,但相同的第一个模板参数...以防万一您想要什么。
还观察到您不再需要
unit_t
概念。以下是一个完整的汇编示例
I suppose you can use the good-old (pre C++20) SFINAE.
For example, given a custom type traits as follows
you can enable/disable
as()
as followsObserve the use of
const
, to accept the case of differentUnit
s with different constness but the same first template argument... just in case is what do you want.Observe also that you don't need the
Unit_T
concept any more.The following is a full compiling example