Skip to content

Template(模板化) function signature

实现思路: primary template + specialization

在下面文章中,对它的实现进行了分析:

1、C++\Programming-paradigm\Generic-programming\Pre-C++20-concept\Detection-idiom

2、Compile-template章节

Example code

1、sean-parent Polymorphic Task Template in Ten

#include<memory>
#include<iostream>
#include<utility>
#include<type_traits>

using namespace std;

template<class >
class task;

//...

template<class R, class ... Args>
class task<R(Args...)>
{
    struct concept;
    template<class F>
    struct model;
    unique_ptr<concept> _p;
public:
    template<class F>
    task(F &&f) :
                    _p(make_unique < model<decay_t<F>> > (forward<F>(f)))
    {
    }
    R operator()(Args ... args)
    {
        return _p->_invoke(forward<Args>(args)...);
    }
};

template<class R, class ... Args>
struct task<R(Args...)>::concept
{
    virtual ~concept() = default;
    virtual R _invoke(Args&&...) = 0;
};

template<class R, class ... Args>
template<class F>
struct task<R(Args...)>::model final : concept
{
    template<class G>
    model(G &&f) :
                    _f(forward<G>(f))
    {
    }
    R _invoke(Args &&... args) override
    {
        return invoke(_f, forward<Args>(args));
    }
    F _f;
};

2、stackoverflow Check if a class has a member function of a given signature # A

#include <type_traits>
#include <iostream>
// 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_serialize
{
    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_serialize<C, Ret(Args...)>
{
private:
    template<typename T>
    static constexpr auto check(T*) -> typename
    std::is_same<
    decltype( std::declval<T>().serialize( 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;
};

struct X
{
    int serialize(const std::string&)
    {
        return 42;
    }
};

struct Y: X
{
};

struct Z
{
};
int main()
{
    std::cout << has_serialize<Y, int(const std::string&)>::value << std::endl; // will print 1
    std::cout << has_serialize<Z, int(const std::string&)>::value << std::endl; // will print 1
}
// g++ --std=c++11 test.cpp