【问题标题】:Detect if a function/operator/method having certain signature is defined检测是否定义了具有特定签名的函数/运算符/方法
【发布时间】: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()与给定的签名兼容呢?
  • 对于我目前的需要,您的第一条语句就足够了,即,如果我可以使用可从我拥有的参数转换的参数调用该方法,然后返回可转换为我需要的类型的结果。但我也想知道如何对类型更严格。
  • 为第一种情况添加了答案:对代码进行简单修改。如果你想更严格(检查确切的签名)......也许你应该更好地解释你到底想要什么。

标签: c++ sfinae


【解决方案1】:

如果你打算检查一个类型是否有一个方法someFunc()兼容(in-vocable with)给定的签名)并返回给定的类型,你可以修改你的代码如下

#include<iostream>
#include<type_traits>
#include<utility>

class X
 { public: int someFunc (int, long) const { return 9; } };

class Y
 { };

template <typename, typename = void>
struct Has_someFunc : public std::false_type
 { };

template <typename T, typename RType, typename ... Args>
struct Has_someFunc<std::tuple<T, RType, Args...>, std::enable_if_t<
   std::is_same_v<RType, 
      decltype(std::declval<T>().someFunc(std::declval<Args>()...))>>>
    : public std::true_type
 { };

template <typename RType, typename ... Args, typename T>
void f (T const & v)
 {
   if constexpr (Has_someFunc<std::tuple<T, RType, Args...>>::value)
      std::cout << "has someFunc()\n";
   else
      std::cout << "has NOT someFunc()\n";
 }

int main()
{
    std::cout << "X "; f<int>(X{});
    std::cout << "X "; f<int, int, long>(X{});
    std::cout << "X "; f<int, int, int>(X{});
    std::cout << "Y "; f<int>(Y{});
}

缺点:第三次调用也会得到“has someFunc()”,因为最后一个参数(int)与最后一个预期参数(long)兼容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-09
    • 2015-06-07
    • 1970-01-01
    • 2021-12-29
    • 1970-01-01
    • 1970-01-01
    • 2017-01-13
    • 1970-01-01
    相关资源
    最近更新 更多