c++ - 检查默认删除的函数模板是否明确专门用于特定类型?
问题描述
(这个问题已经过大量编辑,抱歉。)
假设我有几个非常量函数模板,默认被删除:
template <typename T> void foo() = delete;
template <typename T> int bar(int x) = delete;
// etc.
并且有一些明确的特化作为一般情况删除的例外。
我想编写代码(例如特征类?),给定这些函数之一的标识符和类型 T,在编译时检测指定的函数是否明确专门用于类型 T。代码需要通用的,即不是每个功能的单独检测器。
笔记:
- 寻找 C++11 解决方案。
- 我们可以假设默认情况下会删除指定的函数——如果有帮助的话。
- 理想情况下,它会喜欢
instantiation_exists<decltype(foo), foo, int>::value
或instantiation_exists<int>(foo, tag<int>)
或instantiation_exists(foo, tag<int>)
或类似的东西。
编辑: @Jarod42 在对这个问题的早期版本的评论中写了一个SFINAE 示例,该版本是关于每个单功能检测器的。我尝试使用模板模板参数对其进行概括/泛化:
#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);
但那是一种洗涤(Coliru)。
解决方案
我们不能传递模板函数,或者模板参数中的重载。
我们可以在仿函数中转换这些函数:
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));
我使用通用 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)...);
};
};
推荐阅读
- python - pandas:从第二个数据框的索引创建列
- installshield - 如何将文件安装到系统驱动器的文件夹中
- java - 插入具有重复唯一键的记录时如何获取主键
- r - 闪亮的反应性基础 - 需要反应性包装器吗?如果是这样,哪个和在哪里?
- javascript - 将值作为 js 字典返回,某些值未定义?
- python - Pip install qiskit:命令出错,退出状态为 255:
- sql - 用于连接两个按连接逻辑排序的表的最佳 SQL 查询
- c++ - 如何将 intell-ipp 添加到 qt 5.9
- java - 从 fb 实时数据库中检索数据
- javascript - 如何计算使用 Zebra Datepicker 选择的两个日期的总天数?