使用模板C ++进行类型测试

时间:2020-09-05 02:08:47

标签: c++ templates

所以我有一个函数,它带有两种可能的参数类型,每种类型都是我预定义的lambda函数类型。两种可能性是CellFType和FType。在两种情况下,该函数几乎相同,但是根据功能类型,我需要一行代码来做两种不同的事情。我想避免为此带来额外的负担,因此我将其作为模板

/// Returns the integral 2 norm of a function

template <typename FunctionType>
double norm(const FunctionType &f)
{
    double value = 0.0;

    for (size_t iT = 0; iT < n_cells; iT++)
    {
        QuadratureRule quadT = cell_quads[iT];
        for (size_t iqn = 0; iqn < quadT.size(); iqn++)
        {
            double qr_weight = quadT[iqn].w;

            VectorRd f_on_qr = (typeid(FunctionType) == typeid(FType<VectorRd>) ? 
            f(quadT[iqn].vector()) : f(quadT[iqn].vector(), cells[iT])); // *ERROR*

            value += qr_weight * scalar_product(f_on_qr, f_on_qr);
        }
    }

    return sqrt(value);
}

FType和CellFType也都采用以下模板:

template <typename T>
using CellFType = std::function<T(const VectorRd &, const Cell *)>;

template <typename T>
using FType = std::function<T(const VectorRd &)>;

为什么这会引起问题?如何在此处正确键入测试?

1 个答案:

答案 0 :(得分:0)

注释中的解决方案(调用重载函数)当然是最容易理解的方法,因此也是最佳方法。

但是,有时最好还是全部内联。由于您使用的是C ++ 17,因此std::visit中经常使用该帮助程序类:

template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;  

它需要一堆lambda,并将其转换为带有调用操作符重载的类以调用每个lambda。您也可以使用它来分派案件:

VectorRd f_on_qr = overloaded {
    [&](FType<VectorRd> g) { return g(quadT[iqn].vector()); },
    [&](CellFType<VectorRd> g) { return g(quadT[iqn].vector(), cells[iT])); }
} (f);

概念证明: https://godbolt.org/z/G5qWGK