c++ - 是否可以仅通过标识符检查成员模板的存在?

标签 c++ templates c++14 sfinae typetraits

我们能否检测成员函数模板变量模板/结构/ union 模板alias template 不知道 template/non-template 参数的数量或性质?

当我试着去想这个的时候,我的脑海里什么都想不起来。但是让我们使用成员函数模板来构造:

struct foo
{
    // Really random. Let's assume we don't know this declaration, just the name "bar"
    template <class T, std::size_t N, class... Args>
    void bar(T a, T b, T(&c)[N], Args const& ...);
};

如何检查 foo::bar 模板是否存在?

基于实例化的类型特征在这里不适用,因为(理论上)我们不知道我们应该使用哪些参数以什么顺序和< em>有多少。也许一些神奇的查找方法是合适的?还是根本不可能?


搜索时,我找到了this question ,但答案中的解决方案需要了解 template 的性质。


这是我第一次失败检测struct template的尝试:

struct foo
{
    template<class T>
    struct bar { };
};

template <class T, class = void>
struct has_template_bar : std::false_type
{ };

template <class T>
struct has_template_bar <T, void> : std::true_type
{
    template<template<class...> class tplt_tplt = T::bar> // Invalid default argument
    struct placebo
    { };
};

最佳答案

我可以向您展示如何检测结构模板:

template < class > struct check_template : std::false_type {};

// Specialize for template classes
template <template<class...> class X, class... Args>
struct check_template< X<Args...> > : std::true_type {};

然后你可能可以玩弄 declval , void_t等来检测成员模板。

如果您想检测类型与元类型,即像 std::vector 这样的模板而不是 std::vector<int> ,您可以执行以下操作:

#include <iostream>

template <template<class...> class>
constexpr bool is_template()
{
    return true;
}

template <class>
constexpr bool is_template()
{
    return false;
}

struct Foo{};

template<class>
struct TemplateFoo{};

int main()
{
     std::cout << std::boolalpha;
     std::cout << is_template<Foo>() << std::endl;
     std::cout << is_template<TemplateFoo>() << std::endl;
}

Live on Coliru

请注意,如果元类型具有任何非类型参数,则解决方案将不起作用,例如

template<class, int> struct X{};

关于c++ - 是否可以仅通过标识符检查成员模板的存在?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39811895/

相关文章:

c++ - 使用 Nsight 确定银行冲突和合并

c++ - 为什么我的 Threaded Thrift 调用速度很慢?

子 vector 和成员的 C++ 编译时解释

javascript - if 语句的 Soy 模板语法

c++ - 计算一个数的长度

c++ - 为什么在 vector 重新分配期间没有调用 noexcept 移动构造函数?

c++ - 如何在 Oracle PRO*C 中按名称绑定(bind)

c++ - 如何将模板从 C++ 转换为 C

c++ - 在 Ctor 调用中将 std::initializer_list 与括号括起来的参数分开

c++ - boost::bimap 中的移位值