【发布时间】:2020-03-01 19:31:02
【问题描述】:
来自this 的问题,如果定义了具有特定签名的函数/运算符/方法,我们如何检测(在编译时)?
从链接的问题和查看关于 std::void_t 的 cppreference 我们可以编写(C++17 提前)
#include<iostream>
#include<type_traits>
#include<utility>
class X { public: int someFunc() const{ return 9; } };
class Y{};
template<typename, typename = std::void_t<>> struct Has_someFunc
: std::false_type{};
template<typename T> struct Has_someFunc<T, std::void_t<decltype(std::declval<T>().someFunc())>>
: std::true_type{};
template<typename T>
void f(const T& v){
if constexpr(Has_someFunc<T>::value)
std::cout << "has someFunc()\n";
else
std::cout << "has NOT someFunc()\n";
}
int main()
{
std::cout << "X "; f(X{});
std::cout << "Y "; f(Y{});
return 0;
}
打印出来的
X has someFunc()
Y has NOT someFunc()
但是如果我们想测试一个类型不仅要定义someFunc,还要有特定的签名呢?
虽然我使用的是 C++17,但也欢迎在任何其他版本的标准中回答。
【问题讨论】:
-
您想知道
someFunc()是否可以使用给定的签名调用(这很简单,从您的代码开始)或者是否存在具有给定签名的someFunc()?第二种情况:如果有一个模板someFunc()与给定的签名兼容呢? -
对于我目前的需要,您的第一条语句就足够了,即,如果我可以使用可从我拥有的参数转换的参数调用该方法,然后返回可转换为我需要的类型的结果。但我也想知道如何对类型更严格。
-
为第一种情况添加了答案:对代码进行简单修改。如果你想更严格(检查确切的签名)......也许你应该更好地解释你到底想要什么。