概念<A,B>检查“A”是否源自“B<...something...>”

问题描述 投票:0回答:1

MCVE上帝螺栓链接

我有一个概念

Trait_AActuallyBTemplate<A,B>
来检查
A
是否=
B<...something...>

它有效。

如何创建一个新概念来检查

A
是否继承自
B<...something...>

#include <vector>
#include <iostream>
namespace hid{
    template <typename T,template<typename... Ty> typename B>
    struct is_mytype : std::false_type { };

    template <typename... A,template<typename... Ty> typename B>
    struct is_mytype<B<A...> ,B> : std::true_type { };

};

template <typename T,template<typename... Ty> typename B>
concept Trait_AActuallyBTemplate = hid::is_mytype<T,B>::value;

//vvv please modify here
template <typename T,template<typename... Ty> typename B>
concept Trait_AInheritFromBTemplate = hid::is_mytype<T,B>::value; 
//^^^ please modify here

int main() {
    static_assert(Trait_AActuallyBTemplate<std::vector<int>,std::vector>,"hehe1");
    static_assert(!Trait_AActuallyBTemplate<int,std::vector>,"hehe2");
    struct MyVector : public std::vector<int> {};
    static_assert(Trait_AInheritFromBTemplate<MyVector,std::vector>,"hehe3"); 
    //^^^ Assert fail only here. (It should pass)  I am sad.
}
c++ c++20 c++-concepts
1个回答
0
投票

你所要求的基本上是不可能的,因为

A
可以从任何
B<...>
派生或不派生。 例如:

template <typename...>
struct Base {};

struct Derived : Base<int> {};

如果您现在要检查

Trait_AInheritFromBTemplate<Derived, Base>
是否为真, 编译器必须凭空找出
Derived
是从
Base<int>
派生出来的。

一个非常有限的解决方案是检查是否可以使用以下内容将

Derived
向上转换为
Base

template <typename T>
concept derived_from_base = requires (T& t) {
    { static_cast<T::Base>(t) } -> Trait_AActuallyBTemplate<T, Base>;
};

这是有效的,因为

::Base
命名了
T
中的基类子对象(任何类型
Base<...>
)。

© www.soinside.com 2019 - 2024. All rights reserved.