dev*_*oln 5 c++ templates template-meta-programming c++11
我需要一种可移植的方法来定义模板类,该模板类检查其参数上某些表达式的有效性。理想情况下,它应该在 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。是否有解决这些问题的方法,或者可能有一些不同的方法来进行表达式检查,适用于所有编译器?
以下代码使用我的 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; }
Run Code Online (Sandbox Code Playgroud)
我希望这对我有帮助,并对我的英语不好表示歉意。
- - 编辑 - -
std::declval根据 aschepler 的更正修改后的示例(添加使用)(谢谢!)
---编辑2 ---
按照 PaulMcKenzie 的建议,我在rextester中编译了示例;似乎也适用于 VS 2015。
---编辑3 ---
根据 GLmonster 的观察进行修改(std::remove_reference<U>*而不是U*作为func().
| 归档时间: |
|
| 查看次数: |
1706 次 |
| 最近记录: |