我需要一种可移植的方法来定义模板类,该模板类检查其参数上某些表达式的有效性。理想情况下,它应该在 MSVC 2013+、Clang 3.1+ 和 GCC 4.8+ 中同样工作。
使用示例:
struct MyStruct
{
int Back() {return 5;}
};
static_assert(HasBack<MyStruct>::value, "Back must exist!");
Run Code Online (Sandbox Code Playgroud)
我尝试了这段代码:
template<typename T, typename dummy=void> struct HasBack: std::false_type {};
template<typename T> struct HasBack<T, void_t<decltype(declval<T>().Back())>>: std::true_type {};
Run Code Online (Sandbox Code Playgroud)
它在 clang 中工作,但在 Visual Studio 中不起作用。特别是为此,我使用编译器扩展编写了另一个实现:
template<typename T> struct HasBack
{
__if_exists(void_t<decltype(declval<T>().Back())>) {enum {value=1};}
__if_not_exists(void_t<decltype(declval<T>().Back())>) {enum {value=0};}
};
Run Code Online (Sandbox Code Playgroud)
它可以在 Visual Studio 2013+ 中编译和工作,但它会在包含此代码的任何项目中完全禁用 IntelliSense。是否有解决这些问题的方法,或者可能有一些不同的方法来进行表达式检查,适用于所有编译器?
我正在开发一个应用程序,通过逐渐禁用某些功能和优化,可以使用从 4.6 到 2.0 的任何 OpenGL 版本。这意味着它可以使用 2.0,但更喜欢最新支持的版本,以便能够使用 OpenGL 3.x-4.x 中的所有可用功能。此外,它还处理核心和兼容性上下文之间的所有差异,因此它应该适用于任何配置文件。
看来在 Windows 上不会有问题,因为我可以省略版本和配置文件,并自动获取最新支持版本的兼容性上下文。
但 macOS 和 Mesa 上的工作方式有所不同。在那里,我必须请求某个特定版本的核心前向兼容上下文,即使我不想要特定版本,我想要最新的版本。
我该如何处理这个问题?我是否必须循环尝试所有版本 4.6、4.5、4.4、4.3、4.2、4.1、4.0、3.3、3.2、3.1、3.0、2.1、2.0,直到成功创建上下文?或者有更好的解决方案吗?
如果没有更好的通用解决方案,我想知道它在不同平台上的不同驱动程序的实践中如何工作。