我正在尝试编写一个通用过滤函数,该函数在多维数组(任意等级)中以给定采样坐标执行线性插值。为此,我需要一个递归函数模板,该模板遍历数组的所有维度,直到达到值及其相关类型为止。我使用boost :: enable_if,以检测何时停止迭代通过尺寸。它可以正常工作,直到我尝试将返回值/键入到最高功能为止。为此,我尝试使用C ++ 0x类型推理,但似乎与BOOST :: ENABLE_IF混合在一起。

我将问题隔离到以下内容:

template< typename T, std::size_t I >
auto test(const T &t) -> typename boost::enable_if_c< (I == 0), typename T::value_type >::type
{
    return t[0];
}

template< typename T, std::size_t I >
auto test(const T &t) -> typename boost::enable_if_c< (I > 0), decltype(test< T, I - 1 >(T())) >::type
{
    return test< typename T::value_type, std::size_t(I - 1) >(t[0]);
}

编译器(GCC 4.6)抱怨以下代码:

typedef std::array< std::array< float, 1 >, 1 > myarray;
myarray ma;
std::cout << typeid (test< myarray, 1 >(ma)).name() << std::endl;

错误信息:

error: conversion from 'boost::enable_if_c<true, float>::type' to non-scalar type 'boost::enable_if_c<true, std::array<float, 1u> >::type' requested

即使指示使用test <t,i -1>的测试<t,i> cledtype似乎使用返回值。知道为什么这种行为发生吗?目前,它认为我将把整个东西变成一个函子...

有帮助吗?

解决方案

问题是您将t()()(和t)传给声明。这些类型不会折叠。如果您将返回表达式与传递给声明的内容进行比较,则可以清楚地揭示这一点 - 它们是不一致的。

template< typename T, std::size_t I >
auto test(const T &t) -> typename boost::enable_if_c< (I > 0), decltype(test< T, I - 1 >(T())) >::type
{
    return test< typename T::value_type, std::size_t(I - 1) >(t[0]);
}

decltype: test<T

return expression: test< typename T::value_type

在定义这样的正向函数时,用于定义返回类型的声明表达式几乎应与实际返回表达式完全相同。

编辑:我需要补充一点,您不应该通过rvalues,而实际上您将通过lvalues,尤其是将模板传递给模板,因为您很可能会得到不同的结果。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top