c++ - 类型特征以检测具有 const 变体的特定方法的结构
问题描述
我需要一个特征来检测结构何时具有特定方法。
例如,我想检测结构何时具有两个方法void foo()
and void bar(SomeData)
,否则为 false 。
我在下面的尝试有效,除非结构另外具有所需方法的 const 变体。我希望它也能在这种情况下工作,因为要求只是存在两个非常量变体。
即在下面的代码段中,has_methods<T>
对于 是正确的TypeA
,对于 是错误的TypeB
。
如何调整此代码以同时适用于TypeA
和TypeB
?
template<typename T, typename = void, typename = void>
struct has_methods : std::false_type {};
template<typename T>
struct has_methods<T,
std::void_t<decltype(&T::foo)>,
std::void_t<decltype(&T::bar)>> : std::true_type {};
struct SomeData {};
struct TypeA
{
void foo();
void bar(SomeData);
};
struct TypeB
{
void foo();
void foo() const;
void bar(SomeData);
void bar(SomeData) const;
};
int main()
{
std::cout << "has_methods<TypeA>: " << has_methods<TypeA>::value << std::endl;
std::cout << "has_methods<TypeB>: " << has_methods<TypeB>::value << std::endl;
return 0;
}
期望的输出是:
has_methods<TypeA>: 1
has_methods<TypeB>: 1
解决方案
请注意,您has_methods
实际上并不是在测试方法。&T::foo
匹配任何名为foo
. 如评论中所述,您会得到误报struct C { int foo; std::string bar; };
。幸运的是,您的问题的答案也解决了这个问题。
您可以使用 astatic_cast
来选择所需的重载,如下所示:
template<typename T>
struct has_methods<T,
std::void_t<decltype(static_cast<void (T::*)()>(&T::foo))>,
std::void_t<decltype(static_cast<void (T::*)(SomeData)>(&T::bar))>> : std::true_type {};
请注意,声明SomeData
必须可用(您可以将其设为 的参数has_methods
,但为了简单起见,我只是重新排列了代码以SomeData
首先定义)。完整示例:
#include <type_traits>
#include <iostream>
struct SomeData {};
template<typename T, typename = void, typename = void>
struct has_methods : std::false_type {};
template<typename T>
struct has_methods<T,
std::void_t<decltype(static_cast<void (T::*)()>(&T::foo))>,
std::void_t<decltype(static_cast<void (T::*)(SomeData)>(&T::bar))>> : std::true_type {};
struct TypeA
{
void foo();
void bar(SomeData);
};
struct TypeB
{
void foo();
void foo() const;
void bar(SomeData);
void bar(SomeData) const;
};
int main()
{
std::cout << "has_methods<TypeA>: " << has_methods<TypeA>::value << std::endl;
std::cout << "has_methods<TypeB>: " << has_methods<TypeB>::value << std::endl;
return 0;
}
has_methods<TypeA>: 1
has_methods<TypeB>: 1
(我会添加一些负面因素以进行更有说服力的测试,但我不想对您的代码进行不必要的更改,并且部分是懒惰;)
推荐阅读
- spring - Junit 测试用例因 Method throw 'org.hibernate.LazyInitializationException' 异常而失败
- php - 正确传递参数和 MySQL 查询
- python - FastAPI通过TestClient在get请求中传递json
- asp.net-core - OAuth .NET Core - 使用自定义选项登录后进行许多重定向 - 多租户
- amazon-web-services - 如何为 aws EKS 上的 nodePort 添加规则以允许某些端口范围内的流量?
- react-native - 带有 onLongPress 回调的 FlatList
- api - 我怎样才能接受人类口音(Wavenet 或 Ssml 声音)?
- python - 饼状图上的参数 Matplotlib、百分比大小、颜色
- angular - 如果地址字段为空,如何将地址添加为不适用。否则显示为地址
- haskell - 过滤代数数据类型列表