Rob*_*lck 5 c++ templates opencl
我试图理解为什么我需要在一些openCL代码中使用模板消歧器.
编辑:这是一个最小的复制案例:
//test.hpp
#include <iostream>
#include <vector>
#include "cl.hpp"
template <typename T>
class Foo {
public:
std::vector<cl::Platform> platforms;
std::vector<cl::Device> devices;
Foo();
void bar();
};
template<typename T>
Foo<T>::Foo() {
cl::Platform::get(&platforms);
platforms[0].getDevices(CL_DEVICE_TYPE_GPU, &devices);
}
template<typename T>
void Foo<T>::bar() {
// Fails to compile: error: expected expression
//std::cout << devices[0].getInfo<CL_DEVICE_NAME>() << std::endl;
// Works
std::cout << devices[0].template getInfo<CL_DEVICE_NAME>() << std::endl;
// Also works
cl::Device &mydevice = devices[0];
std::cout << mydevice.getInfo<CL_DEVICE_NAME>() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
和源文件:
//test.cpp
#include "test.hpp"
int main() {
Foo<double> foo = Foo<double>();
foo.bar();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使模板歧义不必要的参考有什么不同?我试图理解歧义在哪里.(另外,我知道我没有在我的班级中使用模板化变量,这只是一个复制问题的最小案例.)
首先,这只是模板代码中的一个典型问题。问题在于,因为在解析时,的性质getInfo是未知的(它是函数模板还是常规成员变量?),解析器不知道是否将其解释<为小于或指定模板参数的开始。
因此\xc2\xa714.2 [temp.names]/4中的规则,其示例是:
\n\ntemplate<class T> void f(T* p) {\n T* p1 = p->alloc<200>(); // ill-formed: < means less than\n T* p2 = p->template alloc<200>(); // OK: < starts template argument list\n T::adjust<100>(); // ill-formed: < means less than\n T::template adjust<100>(); // OK: < starts template argument list\n}\nRun Code Online (Sandbox Code Playgroud)\n\n现在,就你的情况而言,我认为这似乎有点愚蠢,因为这是对的Device?是的,就你而言。但什么是:
template <typename T> struct Wrecker { using type = std::vector<Device>; };\ntemplate <> struct Wrecker<double> { using type = std::vector<Other>; };\n\ntemplate <typename T>\nstruct Foo {\n using Devices = typename Wrecker<T>::type;\n Devices devices;\n\n void bar();\n};\nRun Code Online (Sandbox Code Playgroud)\n\n所以,是的,该规则并不像它应有的那么精确。它可以进一步深入研究冲突并检查是否可以推断出实际类型......
\n\n...但是您是否意识到,事实上,允许您template在某些情况下(非依赖情况)进行省略的简单事实已经需要有史以来最糟糕的编译器黑客之一?传统的管道:标记化 -> 解析 -> 语义分析必须在 C++ 中完全扭曲,以允许在解析阶段提供语义分析反馈foo<4>(),从而自动消除模板调用的歧义。
就我个人而言,我的建议是template系统地强制执行。本来可以省去很多麻烦。