c++ - 可变参数模板函数参数包的过滤

标签 c++ c++11 variadic-functions

我想“过滤”可变参数模板函数的参数包,如下面的代码所示(只需要“过滤”某些类型的变量):

#include <iostream>
#include <utility>
#include <cstdlib>

struct Z {};

struct test
{

    using result_type = void;

    template< typename... P >
    result_type apply_filter(P &&... _p) const
    {
        using std::forward;
        return operator () (forward< P >(_p)...);
    }

    template< typename... T >
    result_type operator () (std::string const & _s, T &&... _tail) const
    {
        std::cout << _s << std::endl;
        return operator () (std::forward< T >(_tail)...);
    }

    template< typename... T >
    result_type operator () (double const & _x, T &&... _tail) const
    {
        std::cout << _x << std::endl;
        return operator () (std::forward< T >(_tail)...);
    }

    template< typename... T >
    result_type operator () (Z const &, T &&... _tail) const
    {
        std::cout << "z" << std::endl;
        return operator () (std::forward< T >(_tail)...);
    }

private :

    result_type operator () () const { return; }

    template< typename T, typename U >
    using is_the_same = std::is_same< typename std::remove_const< typename std::remove_reference< T >::type >::type, U >;

    template< typename T >
    typename std::enable_if< is_the_same< T, std::string >::value, std::string >::type
    forward(T && _s) const
    {
        return "\"" + _s + "\"";
    }

    template< typename T >
    typename std::enable_if< is_the_same< T, double >::value, double >::type
    forward(T && _x) const
    {
        return _x + 1.0;
    }

};

int main()
{
    test test_;
    double x = 0.0;
    std::string s = "s";
    Z z;
    test_.apply_filter(x, s, z);
    return EXIT_SUCCESS;
}

但是std::forward的优先级高于apply_filter中的成员函数。因此这里没有发生过滤。

有什么解决办法吗?

最佳答案

这应该可以解决问题:

#include <iostream>
#include <utility>

struct Z { };

struct test
{

    using result_type = void;

    template< typename... P >
    result_type apply_filter(P &&... _p) const
    {
        return operator () (forward<P>(_p)...);
    }

    template< typename... T >
    result_type operator () (std::string const & _s, T &&... _tail) const
    {
        std::cout << _s << std::endl;
        return operator () (std::forward< T >(_tail)...);
    }

    template< typename... T >
    result_type operator () (double const & _x, T &&... _tail) const
    {
        std::cout << _x << std::endl;
        return operator () (std::forward< T >(_tail)...);
    }

    template< typename... T >
    result_type operator () (Z const &, T &&... _tail) const
    {
        std::cout << "z" << std::endl;
        return operator () (std::forward< T >(_tail)...);
    }

private:

    result_type operator () () const { }

    template< typename T, typename U >
    using is_the_same = std::is_same<typename std::remove_const<typename std::remove_reference<T>::type>::type, U>;

    template<typename T>
    using is_known_type = typename std::conditional<(is_the_same<T, std::string>::value || is_the_same<T, double>::value), std::true_type, std::false_type>::type;

    template<typename T>
    typename std::enable_if<is_the_same<T, std::string>::value, std::string>::type
    forward_impl(T && _s, std::true_type) const
    {
        return "\"" + _s + "\"";
    }

    template<typename T>
    typename std::enable_if<is_the_same<T, double>::value, double>::type
    forward_impl(T && _x, std::true_type) const
    {
        return _x + 1.0;
    }

#define RETURNS(exp) -> decltype(exp) { return exp; }

    template<typename T>
    auto forward_impl(T && t, std::false_type) const
    RETURNS(std::forward<T>(t))

    template<typename T>
    auto forward(T && t) const
    RETURNS(forward_impl(std::forward<T>(t), is_known_type<T>()))

#undef RETURNS
};

int main(int argc, char ** argv) {
    test test_;
    double x = 0.0;
    std::string s = "s";
    Z z;
    test_.apply_filter(x, s, z);

    return 0;
}

关于c++ - 可变参数模板函数参数包的过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18292494/

相关文章:

java - 如何将当前方法的参数放入列表中

scala - 在辅助构造函数中传递可变参数

c++ - 我如何将 boost::mpl::fold 与 boost::fusion::map 一起使用?

c++ - 带有自定义类比较器的 STL 映射不起作用

c++ - 为数组类实现 move 构造函数(右值引用)

c - x86_64 va_list结构的格式是什么?

c++ - SSE 类型的容器

c++ - dyld : Library not loaded: @rpath/libopenblas. 动态库

c++ - 从 cc 编译器切换到 g++ 编译器时出现链接器错误

c++ - 为右值对象调用非常量成员函数是否安全?