2

我正在寻找一种将通用(显然是 constexpr)函数传递给模板的方法。它必须能够在不使用 lambda 的情况下接受任意数量的参数。这是我到目前为止所拥有的:

template<typename T, T(*FUNC)()> struct CALL
{
    static inline constexpr decltype(FUNC()) EXEC()
    {
        return FUNC();
    }
};

但是,这仅在传递的函数不带参数时才有效。有没有办法让模板接受任何 constexpr 函数?传递 std::function 似乎不起作用。我想关键是可变参数模板参数,但我不知道如何在这种情况下利用它们。

4

2 回答 2

7

如果我正确理解您要实现的目标,您可以使用模板函数而不是具有静态函数的模板类:

#include <iostream>

template<typename T, typename... Ts>
constexpr auto CALL(T (*FUNC)(Ts...), Ts&&... args) -> decltype(FUNC(args...))
{
    return FUNC(std::forward<Ts>(args)...);
}

constexpr double sum(double x, double y)
{
    return (x + y);
}

int main()
{
    constexpr double result = CALL(sum, 3.0, 4.0);
    static_assert((result == 7.0), "Error!");
    return 0;
}
于 2013-01-12T21:59:47.300 回答
0
template<int... I>
struct with
{
    template<int F(decltype(I)...)>
    struct call
    {
        static constexpr int value = F(I...);
    };
};

constexpr int f(int i) {return i;}
constexpr int g(int i, int j) {return i + j;}

int main()
{
    int u = with<0>::call<f>::value;
    constexpr int v = with<0, 1>::call<g>::value;
}

请注意,这有一些限制,就像我回答上一个问题一样。但是在编译时仍然可以从非类型模板参数生成一个值。std::integral_constantconstexpr double

#include <iostream>

template<typename T, T... v>
struct with
{
    template<typename R, R f(decltype(v)...)>
    struct call
    {
        static constexpr R value = f(v...);
    };
};

#define AT_COMPILATION(f, x, ...) with<decltype(x), x, ##__VA_ARGS__>::call<decltype(f(x, ##__VA_ARGS__)), f>::value

constexpr long f(long i) {return i;}
constexpr double g(int i, int j) {return static_cast<double>(i) / j;}

int main()
{
    constexpr double u = with<long, 0L>::call<decltype(f(0L)), f>::value;

    std::cout << with<int, 5, 2>::call<double, g>::value << std::endl;

    constexpr double v = AT_COMPILATION(f, 0L);

    std::cout << AT_COMPILATION(g, 5, 2) << std::endl;
}
于 2013-01-13T18:40:03.803 回答