C++ 如何在编译时检查类是否具有继承的函数?

C++ 如何在编译时检查类是否具有继承的函数?,c++,c++11,typetraits,C++,C++11,Typetraits,如果继承了函数push\u back,则显示模板具有\u push\u back功能,该功能不起作用 有没有一种方法可以让它在没有经验的情况下工作?根据答案,您的代码可能如下所示: 1 0 #包括 //带有静态断言的主模板 //获取有意义的错误消息 //如果它被实例化。 //如果我们不在乎的话,我们可以不加定义。 模板 struct有_push _back{ 静态断言( std::整型_常量::值, “第二个模板参数必须是函数类型。”); }; //进行检查的专用化 模板 struct有_pu

如果继承了函数
push\u back
,则显示模板
具有\u push\u back
功能,该功能不起作用

有没有一种方法可以让它在没有经验的情况下工作?

根据答案,您的代码可能如下所示:

1
0
#包括
//带有静态断言的主模板
//获取有意义的错误消息
//如果它被实例化。
//如果我们不在乎的话,我们可以不加定义。
模板
struct有_push _back{
静态断言(
std::整型_常量::值,
“第二个模板参数必须是函数类型。”);
};
//进行检查的专用化
模板
struct有_push _back{
私人:
模板
静态constexpr自动检查(T*)
->字体名
std::是一样的吗<
decltype(std::declval()。push_back(std::declval answer),但它不能处理继承的函数。

根据answer,您的代码可能如下所示:

1
0
#包括
//带有静态断言的主模板
//获取有意义的错误消息
//如果它被实例化。
//如果我们不在乎的话,我们可以不加定义。
模板
struct有_push _back{
静态断言(
std::整型_常量::值,
“第二个模板参数必须是函数类型。”);
};
//进行检查的专用化
模板
struct有_push _back{
私人:
模板
静态constexpr自动检查(T*)
->字体名
std::是一样的吗<
decltype(std::declval().push_back(std::declval answer),但它不能处理继承的函数。

这里使用的是
void\u t
,它是C++17中的标准,并且还附带了其他实用程序,例如库基本原理v2 TS中的
是精确的
,将
has\u push_back
中的大部分工作去掉:

#include <type_traits>

// Primary template with a static assertion
// for a meaningful error message
// if it ever gets instantiated.
// We could leave it undefined if we didn't care.

template<typename, typename T>
struct has_push_back {
    static_assert(
        std::integral_constant<T, false>::value,
        "Second template parameter needs to be of function type.");
};

// specialization that does the checking

template<typename C, typename Ret, typename... Args>
struct has_push_back<C, Ret(Args...)> {
private:
    template<typename T>
    static constexpr auto check(T*)
    -> typename
        std::is_same<
            decltype( std::declval<T>().push_back( std::declval<Args>()... ) ),
            Ret    // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        >::type;  // attempt to call it and see if the return type is correct

    template<typename>
    static constexpr std::false_type check(...);

    typedef decltype(check<C>(0)) type;

public:
    static constexpr bool value = type::value;
};
模板
使用void\u t=void;
模板
使用push_back_test=decltype(std::declval()。push_back(std::declval());
模板
结构具有_push_back:std::false_type{};
模板
struct有_push_back:std::is_same{};
或:

模板
使用push_back_test=decltype(std::declval()。push_back(std::declval());
模板
使用has\u push\u back=std::experimental::是否准确检测到;
如果你想详细了解
void\u t
,我建议你去看看。

这里使用的是
void\u t
,它是C++17中的标准,还附带了一些额外的实用程序,例如
在库基础知识v2 TS中被检测到的
是精确的
,将
的大部分工作都从
推回到

#include <type_traits>

// Primary template with a static assertion
// for a meaningful error message
// if it ever gets instantiated.
// We could leave it undefined if we didn't care.

template<typename, typename T>
struct has_push_back {
    static_assert(
        std::integral_constant<T, false>::value,
        "Second template parameter needs to be of function type.");
};

// specialization that does the checking

template<typename C, typename Ret, typename... Args>
struct has_push_back<C, Ret(Args...)> {
private:
    template<typename T>
    static constexpr auto check(T*)
    -> typename
        std::is_same<
            decltype( std::declval<T>().push_back( std::declval<Args>()... ) ),
            Ret    // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        >::type;  // attempt to call it and see if the return type is correct

    template<typename>
    static constexpr std::false_type check(...);

    typedef decltype(check<C>(0)) type;

public:
    static constexpr bool value = type::value;
};
模板
使用void\u t=void;
模板
使用push_back_test=decltype(std::declval()。push_back(std::declval());
模板
结构具有_push_back:std::false_type{};
模板
struct有_push_back:std::is_same{};
或:

模板
使用push_back_test=decltype(std::declval()。push_back(std::declval());
模板
使用has\u push\u back=std::experimental::是否准确检测到;
如果您想详细了解
void\t
,我建议您签出。

模板
struct有_push _back{
模板<
类型名T,
typename=decltype(
std::declval().向后推(std::declval())
)
>
静态标准::真实型试验(int);
模板
静态标准:假_型试验(长);
使用类型=decltype(测试(0));
静态constexpr bool value=type::value;
};

模板
struct有_push _back{
模板<
类型名T,
typename=decltype(
std::declval().向后推(std::declval())
)
>
静态标准::真实型试验(int);
模板
静态标准:假_型试验(长);
使用类型=decltype(测试(0));
静态constexpr bool value=type::value;
};

为了完整起见,我想发布另一种之前没有提到的方法。
这基于函数的定义和别名声明。
下面是一个简单的工作示例:

template<typename Coll>
struct has_push_back {
    template<
        typename T,
        typename = decltype(
            std::declval<T&>().push_back(std::declval<typename T::value_type>())
        )
    >
    static std::true_type Test(int);

    template<typename T>
    static std::false_type Test(long);

    using type = decltype(Test<Coll>(0));
    static constexpr bool value = type::value;
};
#包括
#包括
#包括
使用名称空间std;
模板
constexpr自动f(int)
->std::有条件的;
模板
constexpr std::false_类型f(char);
模板
使用has_push_back=decltype(f(0));
MyColl类:公共向量{};
int main(){
静态断言(具有push-back::value,“!”;
静态断言(具有push-back::value,“!”;
}

为了完整起见,我想发布另一种之前没有提到的方法。
这基于函数的定义和别名声明。
下面是一个简单的工作示例:

template<typename Coll>
struct has_push_back {
    template<
        typename T,
        typename = decltype(
            std::declval<T&>().push_back(std::declval<typename T::value_type>())
        )
    >
    static std::true_type Test(int);

    template<typename T>
    static std::false_type Test(long);

    using type = decltype(Test<Coll>(0));
    static constexpr bool value = type::value;
};
#包括
#包括
#包括
使用名称空间std;
模板
constexpr自动f(int)
->std::有条件的;
模板
constexpr std::false_类型f(char);
模板
使用has_push_back=decltype(f(0));
MyColl类:公共向量{};
int main(){
静态断言(具有push-back::value,“!”;
静态断言(具有push-back::value,“!”;
}
#include <vector>
#include <type_traits>
#include<utility>

using namespace std;

template<typename T, typename... U>
constexpr auto f(int)
-> std::conditional_t<false, decltype(std::declval<T>().push_back(std::declval<U>()...)), std::true_type>;

template<typename, typename...>
constexpr std::false_type f(char);

template<typename T, typename... U>
using has_push_back = decltype(f<T, U...>(0));

class MyColl : public vector<int> {};

int main() {
    static_assert(has_push_back<vector<int>, int>::value, "!");
    static_assert(has_push_back<MyColl, int>::value, "!");
}