2016-08-22 57 views
4

我想在C++ 11(msvc2013)中编写一个类型特征,这将允许我检查函数类型是否需要某些参数。我不要希望它检查返回类型。我认为这个想法基本上等于std::is_callable,但我很想知道我的方法有什么问题,除了如何真正解决问题。trait检查函数接受某些参数,但不返回类型

我的实现:

namespace traits 
{ 
    namespace detail 
    { 
     template <typename T> 
     struct is_write_function_impl 
     { 
      const char* c = nullptr; 
      size_t l = 0; 

      template<typename U> 
      static auto test(U*)->decltype(declval<U>()(c, l), std::true_type); 
      template<typename U> 
      static auto test(...)->std::false_type; 

      using type = decltype(test<T>(0)); 
     }; 
    } 

    template <typename T> 
    struct is_write_function : detail::is_write_function_impl<T>::type {}; 
} 

我的测试用例:

std::ofstream os; 
auto valid = std::bind(&std::ofstream::write, &os, 
    std::placeholders::_1, std::placeholders::_2); 

// want this to be 'true' but get 'false' 
std::cout << traits::is_write_function<decltype(valid)>::value; 
+0

我听说VS 2013不支持表达式SFINAE,所以它可能无法在VS 2013中实现。 – cpplearner

+0

@cpplearner不知道它是否是苹果和桔子,但我使用这个基本模式来检查类的静态成员函数所有的时间在2013年。我只是无法适应功能对象。 –

回答

5

有相当多的问题,这将通过更好的编译器检测到) - 但是如果你解决这些问题,你的代码

static auto test(U*)->decltype(declval<U>()(c, l), std::true_type); 
           #1   #2  #3 
    :将与VS 2013工作(与12.0.31101.00更新4测试) 0
  1. 这应该是std::declval
  2. 即使在未推导的上下文中,您也不能在static成员函数声明中引用非static数据成员。这应该是(std::declval<char const*>(), std::declval<std::size_t>())
  3. std::true_type是一种类型,并且decltype是表达式上下文。写std::true_type{}

Example

+0

谁需要一个更好的编译器与这样的质量帮助? :) –

相关问题