【问题标题】:How to get the type of function pointer of templated function from invocation如何从调用中获取模板化函数的函数指针类型
【发布时间】:2021-10-28 20:12:53
【问题描述】:

假设我有一些复杂的模板函数,我想测试它是否按预期工作。 特别是当使用某些参数调用时,该函数类型仅由第一个参数确定。 对于example

template<typename T>
bool less(const T& x, const std::type_identity_t<T>& y){
    return x < y;
}

在这里,我想检查一下(使用static_assert 或某些测试框架期望),只有第一个参数决定了函数的签名,例如:

  std::is_same_v<decltype(less(short{1}, long{2})) , decltype(less(short{1}, double{2}))>;

但显然这不起作用,因为 decltype 会给我函数调用的结果,而不是当我给它我给它的参数时实例化的函数的类型。

有没有办法做到这一点(假设我不能修改函数,例如,用 typedefed T 使其成为仿函数或以任何其他方式更改它)?

我试图搜索这个,失败了,我想有人已经问过这个但我找不到问题。

注意:我知道测试行为,而不是实现。例子只是小例子,不现实。

【问题讨论】:

标签: c++ templates c++20 decltype


【解决方案1】:

这不是一个完整的答案,但像 should_convert_to 这样的东西可能有助于测试 less 函数:

#include <type_traits>

template <typename expected>
struct should_convert_to{
    template <typename actual>
    operator actual() {
        static_assert(std::is_same_v<expected, actual>);
        return {};
    }
};
auto result = less(int{1}, should_convert_to<int>());
static_assert(std::is_same_v<decltype(result), bool>);

// error: static_assert failed due to requirement 'std::is_same_v<short, int>'
// less(int{1}, should_convert_to<short>()); 

【讨论】:

    【解决方案2】:

    您可以使用为您提供签名的包装类:

    // ...
    
    template <typename, typename, typename = void>
    struct less_fptr;
    
    template <typename X, typename Y>
    struct less_fptr<X, Y, std::enable_if_t<!std::is_convertible_v<Y, X>>> {
        using type = less_fptr<X, Y>;
    };
    
    template <typename X, typename Y>
    struct less_fptr<X, Y, std::enable_if_t<std::is_convertible_v<Y, X>>> {
        using type = bool(*)(const X&, const std::type_identity_t<X>&);
    };
    
    // ...
    
    static_assert(std::is_same_v<typename less_fptr<decltype(short{1}), decltype(long{2})>::type, typename less_fptr<decltype(short{1}), decltype(double{2})>::type>);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-02-22
      • 2023-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-04
      • 1970-01-01
      相关资源
      最近更新 更多