gpt4 book ai didi

c++ - 检查表达式是否编译的可移植方法

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:42:49 24 4
gpt4 key购买 nike

我需要一种可移植的方式来定义一个模板类,该模板类检查其参数的某些表达式的有效性。理想情况下,它应该在 MSVC 2013+、Clang 3.1+ 和 GCC 4.8+ 中以相同的方式工作。

使用示例:

struct MyStruct
{
int Back() {return 5;}
};
static_assert(HasBack<MyStruct>::value, "Back must exist!");

我试过这段代码:

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 {};

它在 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};}
};

它在 Visual Studio 2013+ 中编译和工作,但它在包含此代码的任何项目中完全禁用 IntelliSense。这些问题是否有解决方法,或者是否有一些不同的方法来进行表达式检查,适用于所有编译器?

最佳答案

以下代码使用我的 g++ (4.9.2) 和我的 clang++ (3.5) 编译。

抱歉,我没有 MSVC,所以我不确定它是否适合你。

#include <utility>
#include <type_traits>

template <typename T>
struct HasBack
{
template<typename U>
static decltype(std::declval<U>().Back(), std::true_type{}) func (std::remove_reference_t<U>*);

template<typename U>
static std::false_type func (...);

using type = decltype(func<T>(nullptr));

static constexpr bool value { type::value };
};

struct MyStruct
{ int Back() {return 5;} };

static_assert(true == HasBack<MyStruct>::value, "yes");
static_assert(false == HasBack<int>::value, "no");

int main ()
{ return 0; }

我希望这对我的英语不好感到抱歉。

--- 编辑 ---

修改示例(添加使用 std::declval )根据 aschepler 的更正(谢谢!)

--- 编辑 2 ---

按照 PaulMcKenzie 的建议,我编译了 rextester 中的示例;似乎也适用于 VS 2015。

--- 编辑 3 ---

根据 GLmonster 的 osservation(std::remove_reference<U>* 而不是 U* 作为 func() 的第一个版本的参数进行修改。

关于c++ - 检查表达式是否编译的可移植方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38797130/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com