评估表达模板通常当您将结果保存到某些special键入如下:
Result D = A*B+sin(C)+3.;
表达式的结果类型:
A*B+sin(C)+3.
is not Result,但它可以转换为Result。评估发生在这种转换过程中。
我的问题是:是否有任何技术(例如,使用占位符?)来识别 D 的值实际上未使用
这样的“转变”:
Result D = A*B+sin(C)+3.;
Result F = D*E;
to
Result F = (A*B+sin(C)+3.)*E;
当您不评估 D 时,这是可能的。为此,通常您应该捕获 D,因为它是真实的,表达类型。例如,在auto:
auto &&D = A*B+sin(C)+3.;
Result F = D*E;
但是,您应该小心 - 有时表达式模板会捕获对其操作数的引用,并且如果您有一些rvalue其表达式后将过期:
auto &&D = A*get_large_rvalue();
// At this point, result of **get_large_rvalue** is destructed
// And D has expiried reference
Result F = D*E;
Where 获取大右值 is:
LargeMatrix get_large_rvalue();
其结果是rvalue,它在完整表达结束时到期获取大右值被称为。如果表达式中的某些内容将存储指向它的指针/引用(以供以后求值)并且您将“推迟”求值 - 指针/引用将比指向/引用的对象更长寿。
为了防止这种情况,您应该这样做:
auto &&intermediate = get_large_rvalue(); // it would live till the end of scope
auto &&D = A*intermediate ;
Result F = D*E;
我不熟悉 C++11,但据我了解, auto 要求编译器从变量的初始化中确定变量的类型
对,就是这样。这就是所谓的类型推断/演绎.
C++98/03 仅针对模板函数进行类型推导,在 C++11 中auto.
你知道 CUDA 和 C++11 是如何交互的吗?
我没用过CUDA(虽然我用过OpenCL),但我想不会有任何问题Host使用 C++11 编写代码。也许某些 C++11 功能不受支持Device代码,但为了你的目的 - 你需要auto只有在Host code
最后,只用C++有可能吗?
您是指 C++11 之前的版本吗? IE。 C++98/C++03?
是的,这是可能的,但它有更多的语法噪音,也许这就是拒绝它的理由:
// somehwhere
{
use_D(A*B+sin(C)+3.);
}
// ...
template<typename Expression>
void use_D(Expression D) // depending on your expression template library
// it may be better to use (const Expression &e)
{
Result F = D*E;
}
我现在在 Windows 下使用 CUDA/Visual Studio 2010。您能否为两个操作系统推荐一个编译器/工具集/环境,以便在我感兴趣的框架中使用 C++11(GPGPU 和 CUDA,您知道吗)
MSVC 2010 确实支持 C++11 的某些部分。特别是它支持auto。所以,如果你只需要auto从 C++11 - MSVC2010 可以。
但如果您可以使用 MSVC 2012 - 我建议坚持使用它 - 它具有更好的 C++11 支持。
另外,技巧 auto &&intermediate = get_large_rvalue();似乎对第三方用户不“透明”(第三方用户不应该知道这样的问题)。我对吗?还有其他选择吗?
如果表达式模板存储对某些值的引用,并且您推迟了它的评估。您应该确保所有引用在评估位置都有效。使用任何你想要的方法 - 它可以在没有 auto 的情况下完成,例如:
LargeMatrix temp = get_large_rvalue();
或者甚至可能是全局/静态变量(不太优选的方法)。
最后一个评论/问题:使用 auto &&D = A*B+sin(C)+3。;看来我应该重载operator=来进行两个表达式之间的赋值,对吧?
不,这种形式不需要复制/移动赋值运算符或复制/移动构造函数。
基本上它只是命名临时值,并将其生命周期延长到范围的末尾。检查这个SO.
但是,如果您使用另一种形式:
auto D = A*B+sin(C)+3.;
在这种情况下,可能需要复制/移动/转换构造函数才能编译(尽管编译器可以使用以下方法来优化实际的复制)复制省略)
此外,使用 auto (用于中间表达式)和 Result 之间的切换来强制计算对于第三方用户来说似乎是不透明的。还有其他选择吗?
我不确定是否还有其他选择。这是表达式模板的本质。当您在表达式中使用它们时 - 它们返回一些内部中间类型,但是当您存储到某些“特殊”类型时 - 会触发评估。