使用受限功能时的尾随返回类型问题

时间:2014-08-24 19:09:53

标签: c++ templates c++11 template-meta-programming c++-amp

我正在使用C ++ AMP为内部编写一个库,我发现以下内容不起作用,我很好奇为什么(因为它可以从仿函数中删除restrict(amp)):

template <typename T>
using SumType = decltype( std::declval<T>() + std::declval<T>() );

template <typename T, typename Func>
auto TestFunc(T t, Func f) -> SumType<decltype(f(t))>
{
    return f(t) + f(t);
}

int main() {
    auto f = []( float flVal ) restrict(amp) {
         return flVal * flVal;
    };

    float flResult = TestFunc( 1.0f, f ); // Error here: "no instance of function template 'TestFunc' matches the argument list"
}

但是,如果我从restrict(amp)的定义中删除f,程序将按预期编译。 AMP开放标准中是否有一个条款可以阐明这一点?


此外,如果我们在TestFunc的定义中使用以下内容,即使使用restrict(amp)说明符,它也能正确编译:

template <typename T, typename Func>
auto TestFunc( T t, Func f ) -> T
{
    return f(t) + f(t);
}

2 个答案:

答案 0 :(得分:1)

我相信你想要的是AMP Specification的第2.2节。您收到错误&#34;没有函数模板实例&#39; TestFunc&#39;匹配参数列表&#34;因为你调用TestFunc的代码不在内部并且限制(amp)lambda(作为parallel_for_each的一部分。因此编译器正在寻找一个带有restrict(cpu)装饰的TestFunc。 / p>

如果您按如下方式更改声明,您的代码是否会编译:

    auto f = [](float flVal) restrict(amp, cpu) {
        return flVal * flVal;
    };

在AMP parallel_for_each的上下文之外调用放大器限制函数/ lambda有点无意义,永远不会起作用。即使你可以欺骗编译器没有错误。

答案 1 :(得分:0)

restrict关键字告诉编译器只有一个指向该对象的指针 这允许编译器进行各种优化。

但是,您的TestFunc正在按值接收指针函数。所以编译器已经知道你试图通过制作该指针的副本来欺骗它。

为避免复制,请通过引用传递参数:

template <typename T, typename Func>
auto TestFunc(T t, Func& f) -> SumType<decltype(f(t))>
{
    return f(t) + f(t);
}