Nicolas Holthaus Nicolas Holthaus - 8 months ago 40
C++ Question

trait to check function accepts certain parameters but not return type

I'm trying to write a type trait in c++11 (msvc2013) that will allow me to check that a function type takes certain parameters. I don't want it to check the return type. I think the idea is basically equivalent to

, but I'm interested in knowing what's wrong with my approach, in addition to how to actually solve the problem.

my implementation:

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

my test case:

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;


There's quite a few issues, which would be detected by a better compiler ;) - but if you fix them, your code will work with VS 2013 (tested with 12.0.31101.00 Update 4):

static auto test(U*)->decltype(declval<U>()(c, l), std::true_type);
                               #1           #2     #3
  1. This should be std::declval.
  2. You can't refer to non-static data members in the declaration of a static member function, even within a non-deduced context. This should be (std::declval<char const*>(), std::declval<std::size_t>()).
  3. std::true_type is a type, and decltype is an expression context. Write std::true_type{}.