c++ - 检查默认删除的函数模板是否明确专门用于特定类型?

标签 c++ c++11 template-meta-programming template-instantiation delete-keyword

(这个问题已经过大量编辑,抱歉。)

假设我有几个非常量函数模板,默认被删除:

template <typename T> void foo() = delete;
template <typename T> int  bar(int x) = delete;
// etc.

并且有一些明确的特化作为一般情况删除的异常(exception)。

我想编写代码(例如特征类?),给定这些函数之一的标识符和类型 T,在编译时检测指定函数是否明确专门用于类型 T。代码需要通用的,即不是每个功能的单独检测器。

笔记:
  • 寻找 C++11 解决方案。
  • 我们可以假设默认情况下会删除指定的函数——如果有帮助的话。
  • 理想情况下,它会喜欢 instantiation_exists<decltype(foo), foo, int>::valueinstantiation_exists<int>(foo, tag<int>)instantiation_exists(foo, tag<int>)或类似的规定。


  • 编辑: @Jarod42 写了一个 SFINAE example在对该问题的早期版本的评论中,该版本是关于单功能检测器的。我尝试使用模板模板参数对其进行概括/泛化:
    #include <type_traits>
    
    template <typename T> void foo() = delete;
    template <> void foo<int>() {}
    
    template <template<typename U> typename F, typename T, typename = decltype(F<T>()) >
    std::true_type test(int);
    
    template  <template<typename U> typename F, typename T>
    std::false_type test(...);
    
    template <typename T>
    using foo_is_defined = decltype(test<foo<T>, T>(0));
    
    static_assert(foo_is_defined<int>::value);
    static_assert(not foo_is_defined<int*>::value);
    

    但那是 a wash (科利鲁)。

    最佳答案

    我们不能传递模板函数,或者模板参数中的重载。

    我们可以在仿函数中转换这些函数:

    template <typename T>
    struct identity_type
    {
        using type = T;  
    };
    
    template <typename F, typename T, typename = decltype(std::declval<F>()(identity_type<T>{})) >
    std::true_type test(int);
    
    template  <typename F, typename T>
    std::false_type test(...);
    
    auto foos = [](auto tag, auto&&... args)
    -> decltype(foo<typename decltype(tag)::type>((decltype(args))(args)...))
    {
        return foo<typename decltype(tag)::type>((decltype(args))(args)...);
    };
    
    template <typename T>
    using is_foo = decltype(test<decltype(foos), T>(0));
    

    Demo

    我使用通用 lambda,所以 C++14。

    在 C++11 中,它会非常冗长:
    struct foos
    {
        template <typename T, typename... Ts>
        auto operator()(identity_type<T>, Ts&&... args) const
        -> decltype(foo<T>(std::forward<Ts>(args)...))
        {
            return foo<T>(std::forward<Ts>(args)...);
        };
    };
    

    关于c++ - 检查默认删除的函数模板是否明确专门用于特定类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61014513/

    相关文章:

    c++ - std future 异常 - 已检索,std bug?

    c++ - 元函数计算 x^n 并在不可能的情况下返回整数限制而不溢出?

    C++:将 POD 添加到 std::vector<char> 中的下一个位置

    c++ - 'network-caching'选项在vlc中使用了Live555的哪些函数

    c++ - ffmpeg 不解码某些 h264 流

    c++ - memory_order_relaxed 的使用

    c++ - 跳过显式模板初始化以避免双重初始化

    C++ 函数指针语法。为什么 (*) 有效但 * 无效?

    C++ 基模板类虚方法没有出现在派生中?

    haskell - 在 Haskell 中处理来自外部文件的标准准引用