Jar*_*ock 12 c++ sfinae type-traits c++-concepts
我的应用程序中有一个问题,我想声明函数应用程序将被编译器拒绝.有没有办法用SFINAE来检查?
例如,假设我想验证std::transform的const范围是违法的.这是我到目前为止所拥有的:
#include <algorithm>
#include <functional>
#include <iostream>
namespace ns
{
using std::transform;
template<typename Iterator1, typename Iterator2, typename UnaryFunction>
  struct valid_transform
{
  static Iterator1 first1, last1;
  static Iterator2 first2;
  static UnaryFunction f;
  typedef Iterator2                   yes_type;
  typedef struct {yes_type array[2];} no_type;
  static no_type transform(...);
  static bool const value = sizeof(transform(first1, last1, first2, f)) == sizeof(yes_type);
};
}
int main()
{
  typedef int *iter1;
  typedef const int *iter2;
  typedef std::negate<int> func;
  std::cout << "valid transform compiles: " << ns::valid_transform<iter1,iter1,func>::value << std::endl;
  std::cout << "invalid transform compiles: " << ns::valid_transform<iter1,iter2,func>::value << std::endl;
  return 0;
}
不幸的是,我的特质拒绝了合法和非法案件.结果:
$ g++ valid_transform.cpp 
$ ./a.out 
valid transform compiles: 0
invalid transform compiles: 0
您的问题类似于SFINAE + sizeof = detector if expressioncompiles。
该答案的摘要:sizeof评估传递给它的表达式的类型,包括实例化函数模板,但它不生成函数调用。这就是 Lol4t0 的观察结果sizeof(std::transform(iter1(), iter1(), iter2(), func()))即使  std::transform(iter1(), iter1(), iter2(), func())不编译也能编译的原因。
您的具体问题可以通过评估 Lol4t0 的答案中的模板来解决,以获取要提供给 的任何输出范围std::transform。然而,在模板中验证函数调用是否会编译的一般问题似乎无法用该sizeof + SFINAE技巧来解决。(它需要一个可从运行时函数调用派生的编译时表达式)。
您可能想尝试ConceptGCC,看看这是否允许您以更方便的方式表达必要的编译时检查。