如何使用static_assert给定的函数调用表达式是否可以编译?

时间:2016-07-13 15:10:18

标签: c++ c++11 c++14 variadic-templates c++17

有没有办法检查函数调用表达式是否会在compile和static_assert上编译?或者我应该只通过system()调用编译器并检查退出代码?

#include <type_traits>

template < typename... Args >
void f(Args && ... args, bool);

template < typename... Args >
void g(Args && ... args);

int main()
{
    g(1, 2.0, "hello", false);  //  compiles
    f(1, 2.0, "hello", false);  //  doesn't compile
    //  How do I do this?
    //  static_assert(!does_this_compile(f(1, 2.0, "hello", false)), "As expected");
}

2 个答案:

答案 0 :(得分:4)

首先将调用结果包装成一个类型:

template<class...Args>
using f_r=decltype(f(std::declval<Args>()...));

现在f_r<int>是调用f并且int rvalue的类型。

接下来写下这个:

namespace details{
  template<template<class...>class Z, class, class...Ts>
  struct can_apply:std::false_type{};
  template<template<class...>class Z, class...Ts>
  struct can_apply<Z,std::void_t<Z<Ts...>>,Ts...>:std::true_type{};
}
template<template<class...>class Z, class...Ts>
struct can_apply:details::can_apply<Z,void,Ts...>;

现在使用它:

template<class...Args>
using can_f = can_apply<f_r, Args...>;

这给了我们:

static_assert(!can_f<int, double, decltype("hello"), bool>{}, "As expected");

这只检查早期错误,基本上是在解析正文之前被捕获的错误。 (SFINAE“错误”)以后的错误被允许致命且无法检查。

答案 1 :(得分:2)

我认为这可能更简单,但是......

如果您可以将函数插入结构({ name: 'bankId',label: 'bankId', align:'left', width: 10,hidden:true }, { name: 'fdicNumber', label: 'fdicNumber',width: 70, key: true, formatter: "showlink", formatoptions: { baseLinkUrl: testUrl, idName: "", addParam: function (options,rowObject) { // return "clientid="+options.rowid+" ; return "clientid="+options.bankId+" ; } } }, 的{​​{1}}和fooF的{​​{1}},在以下示例中)f()(和fooG}具有相同名称(g())的成员,如果他们可以返回与constexpr不同的类型(或const部分,则不会至少我的clang ++)),那么你可以创建几个Func() void函数;然后,您可以在constexpr

中使用constexpr

以下示例适用于g ++ 4.9.2和clang ++ 3.5

checkCompile()

p.s。:也应该适用于C ++ 11。

p.s.2:抱歉我的英语不好。