Note that there are some explanatory texts on larger screens.

plurals
  1. POtraits for testing whether func(args) is well-formed and has required return type
    primarykey
    data
    text
    <p>There are a number of similar questions/answers, but I couldn't quite put those answers together to serve my purposes. I want a traits</p> <pre><code>template&lt;typename Func, typename ReturnType, typename... Args&gt; struct returns_a { static const bool value; }; </code></pre> <p>such that</p> <pre><code>returns_a&lt;F,T,Args&gt;::value </code></pre> <p>is true if <code>F(Args)</code> is well formed and returns a <code>T</code>. After some more research, I got it working as follows:</p> <pre><code>// value is true if Func(Args...) is well formed template&lt;typename Func, typename... Args&gt; class is_callable { template &lt;typename F&gt; static decltype(std::declval&lt;F&gt;()(std::declval&lt;Args&gt;()...), void(), 0) test(int); template &lt;typename&gt; static void test(...); public: static const bool value = !std::is_void&lt;decltype(test&lt;Func&gt;(0))&gt;::value; }; // return_type&lt;FunctionSignature&gt;::type is the return type of the Function template&lt;typename&gt; struct return_type {}; template&lt;typename ReturnType, typename... Args&gt; struct return_type&lt;ReturnType(Args...)&gt; { typedef ReturnType type; }; // helper class, required to use SFINAE together with variadic templates parameter // generic case: Func(Args...) is not well-defined template &lt;typename Func, typename ReturnType, typename dummy, typename... Args&gt; struct returns_a_helper { static const bool value = false; }; // Func is a function signature template &lt;typename Func, typename ReturnType, typename... Args&gt; struct returns_a_helper&lt;Func, ReturnType, typename std::enable_if&lt;std::is_function&lt;Func&gt;::value&gt;::type, Args...&gt; { static const bool value = std::is_convertible&lt;typename return_type&lt;Func&gt;::type, ReturnType&gt;::value; }; // Func(Args...) not a function call, but well-defined template &lt;typename Func, typename ReturnType, typename... Args&gt; struct returns_a_helper&lt;Func,ReturnType,typename std::enable_if&lt;is_callable&lt;Func&gt;::value &amp;&amp; !std::is_function&lt;Func&gt;::value &gt;::type, Args...&gt; { static const bool value = std::is_convertible&lt;typename std::result_of&lt;Func(Args...)&gt;::type, ReturnType&gt;::value; }; template &lt;typename Func, typename ReturnType, typename... Args&gt; struct returns_a : returns_a_helper&lt;Func, ReturnType, void, Args...&gt; {}; </code></pre> <p>which now works fine for functors and functions. Here is a simple test:</p> <pre><code>struct base { virtual bool member(int) const = 0; }; struct foo : base { bool member(int x) const { return x&amp;2; } }; struct bar { foo operator()() { return foo(); } }; foo free_function() { return foo(); } template&lt;typename T, typename Func&gt; void test(Func const&amp;func) { std::cout &lt;&lt; std::boolalpha &lt;&lt; returns_a&lt;Func,T&gt;::value &lt;&lt; std::endl; } int main() { foo x; bar m; test&lt;const base&amp;&gt;([&amp;]() { return x; }); test&lt;const base&amp;&gt;(m); test&lt;const base&amp;&gt;(free_function); return 0; } </code></pre> <p>Well, this works, but it seems a bit cumbersome. Anybody has better/more elegant/shorter solutions?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload