C++11 boost::range::与重复参数组合

C++11 boost::range::与重复参数组合,c++11,boost,variadic-templates,boost-range,C++11,Boost,Variadic Templates,Boost Range,我想使用boost::range::combine作为笛卡尔幂,而不仅仅是一个产品 因此,不要使用这样的表达式boost::range::combine(myRange,myRange,myRange)编写类似于myCombine的东西(myRange,3) 它是如何实现的?在C++17或C++14中实现这一点会更容易、更简洁,但由于您将其标记为一个兼容的实现。这里有一种调用函数对象f的通用方法,相同的参数重复N次 首先,我们需要一种方法来绑定泛型函数对象f的第一个参数,然后接受任意数量的参数:

我想使用
boost::range::combine
作为笛卡尔幂,而不仅仅是一个产品

因此,不要使用这样的表达式
boost::range::combine(myRange,myRange,myRange)编写类似于myCombine的东西(myRange,3)


它是如何实现的?

在C++17或C++14中实现这一点会更容易、更简洁,但由于您将其标记为一个兼容的实现。这里有一种调用函数对象
f
的通用方法,相同的参数重复
N次

首先,我们需要一种方法来绑定泛型函数对象
f
的第一个参数,然后接受任意数量的参数:

template <typename TF, typename T>
struct bound
{
    TF _f;
    T _x;

    template <typename TFFwd, typename TFwd>
    bound(TFFwd&& f, TFwd&& x)
        : _f{std::forward<TFFwd>(f)}, _x{std::forward<TFwd>(x)}
    {
    }

    template <typename... Ts>
    auto operator()(Ts&&... xs)
        -> decltype(_f(_x, std::forward<Ts>(xs)...))
    {
        return _f(_x, std::forward<Ts>(xs)...);
    }
};

template <typename TF, typename T>
auto bind_first(TF&& f, T&& x)
    -> decltype(bound<TF&&, T&&>(std::forward<TF>(f), std::forward<T>(x)))
{
    return bound<TF&&, T&&>(std::forward<TF>(f), std::forward<T>(x));
}
最后,我们可以提供一个很好的界面:

template <std::size_t TN, typename TF, typename T>
auto call_with_same_arg(TF&& f, T&& x)
    -> decltype(helper<TN - 1>{}(std::forward<TF>(f), std::forward<T>(x)))
{
    return helper<TN - 1>{}(std::forward<TF>(f), std::forward<T>(x));
}
模板
自动调用参数相同的参数(TF&&f、T&&x)
->decltype(helper{}(std::forward(f),std::forward(x)))
{
返回帮助程序{}(std::forward(f),std::forward(x));
}
用法:

int add(int a, int b, int c)
{
    return a + b + c;   
}

int main()
{
    assert(call_with_same_arg<3>(add, 5) == 15);
}
intadd(inta,intb,intc)
{
返回a+b+c;
}
int main()
{
断言(使用相同的参数调用参数(add,5)==15);
}


下面是一个完整的C++17实现:

template <std::size_t TN, typename TF, typename T>
decltype(auto) call_with_same_arg(TF&& f, T&& x)
{
    if constexpr(TN == 1)
    {
        return f(x);
    }
    else
    {
        return call_with_same_arg<TN - 1>(
            [&](auto&&... xs){ return f(x, std::forward<decltype(xs)>(xs)...); }, x);
    }
}
模板
decltype(自动)调用参数相同的参数(TF&&f,T&&x)
{
如果constexpr(TN==1)
{
返回f(x);
}
其他的
{
使用相同参数返回呼叫(
[&](auto&&…xs){返回f(x,std::forward(xs)…);},x);
}
}


为完整起见,C++14实现:

template <std::size_t TN>
struct helper
{
    template <typename TF, typename T>
    decltype(auto) operator()(TF&& f, T&& x)
    {
        return helper<TN - 1>{}(
            [&](auto&&... xs){ return f(x, std::forward<decltype(xs)>(xs)...); }, x);
    }
};

template <>
struct helper<0>
{
    template <typename TF, typename T>
    decltype(auto) operator()(TF&& f, T&& x)
    {
        return f(x);
    }
};

template <std::size_t TN, typename TF, typename T>
decltype(auto) call_with_same_arg(TF&& f, T&& x)
{
    return helper<TN - 1>{}(std::forward<TF>(f), std::forward<T>(x));
}
模板
结构辅助程序
{
模板
decltype(自动)运算符()(TF&&f、T&&x)
{
返回帮助程序{}(
[&](auto&&…xs){返回f(x,std::forward(xs)…);},x);
}
};
模板
结构辅助程序
{
模板
decltype(自动)运算符()(TF&&f、T&&x)
{
返回f(x);
}
};
模板
decltype(自动)调用参数相同的参数(TF&&f,T&&x)
{
返回帮助程序{}(std::forward(f),std::forward(x));
}

谢谢你的回答。如果你有其他C++标准的解决方案,请在这里写出来。我刚刚写了c++11,以表明它可能是(而且确实是)模板元编程技巧。对于c++14,是否有与c++17相同的简单解决方案?@YaroslavKishchenko:稍微长一点,但比c++11好。将在一秒钟内发布。@YaroslavKishchenko:完成。您基本上不需要先绑定
bind
bind\u
。非常感谢。我会分析你的答案,然后批准它)
template <std::size_t TN>
struct helper
{
    template <typename TF, typename T>
    decltype(auto) operator()(TF&& f, T&& x)
    {
        return helper<TN - 1>{}(
            [&](auto&&... xs){ return f(x, std::forward<decltype(xs)>(xs)...); }, x);
    }
};

template <>
struct helper<0>
{
    template <typename TF, typename T>
    decltype(auto) operator()(TF&& f, T&& x)
    {
        return f(x);
    }
};

template <std::size_t TN, typename TF, typename T>
decltype(auto) call_with_same_arg(TF&& f, T&& x)
{
    return helper<TN - 1>{}(std::forward<TF>(f), std::forward<T>(x));
}