title: return value from possible type in std::variant through std::visit
body: <p>I am trying to wrap my head around <code>std::variant</code> and <code>std::visit</code> and I am trying to come up with a method to specify a couple of types that I would like my variable to hold (which would go into my <code>std::variant</code>) and then retrieve stored data through a <code>std::visit</code>. Consider the following example:</p>
  <pre class="lang-cpp prettyprint-override"><code>#include &lt;iostream&gt;
  #include &lt;variant&gt;
  #include &lt;string&gt;
  
  struct PrintType {
    void operator()(const int &amp;data) {
      std::cout &lt;&lt; &quot;visiting int node&quot; &lt;&lt; std::endl;
    }
    void operator()(const double &amp;data) {
      std::cout &lt;&lt; &quot;visiting double node&quot; &lt;&lt; std::endl;
    }
  };
  
  struct SingleOperatorOverload {
    int operator()(const int &amp;data) {
      std::cout &lt;&lt; &quot;visiting int node&quot; &lt;&lt; std::endl;
      return data;
    }
  };
  
  struct AllTypesOperatorOverload {
    int operator()(const int &amp;data) {
      std::cout &lt;&lt; &quot;visiting int node&quot; &lt;&lt; std::endl;
      return data;
    }
    double operator()(const double &amp;data) {
      std::cout &lt;&lt; &quot;visiting double node&quot; &lt;&lt; std::endl;
      return data;
    }
  };
  
  int main() {
  
    using var_t = std::variant&lt;int, double&gt;;
  
    // print int related operator() content, OK
    var_t foo = 42;
    std::visit(PrintType(), foo);
  
    // print double related operator() content, OK
    foo = 3.1415;
    std::visit(PrintType(), foo);
  
    // get value and store into bar, struct with single operator(), OK
    foo = 42;
    auto bar = std::visit(SingleOperatorOverload(), foo);
    std::cout &lt;&lt; &quot;bar: &quot; &lt;&lt; bar &lt;&lt; std::endl;
  
    // get value and store into bar, struct with multiple operator(), ERROR
    auto bar = std::visit(AllTypesOperatorOverload(), foo);
    std::cout &lt;&lt; &quot;bar: &quot; &lt;&lt; bar &lt;&lt; std::endl;
  
    return 0;
  }
  </code></pre>
  <p>The variant is allowed to hold (in this simplified example) either <code>int</code> or <code>double</code>. If I just want to print something based on the type (as done with the <code>PrintType</code> struct), that works fine.</p>
  <p>If I want to retrieve data through a visitor as done in the <code>SingleOperatorOverload</code> class, which only provides an implementation for the <code>operator()</code> accepting an int as a parameter, that works. However, as soon as I try to implement an <code>operator()</code> for each type in the <code>std::variant</code>, i.e. here <code>int</code> and <code>double</code>, as in the <code>AllTypesOperatorOverload</code> struct, I get a compilation error <code>error: invalid conversion from '...' {aka double ...} to '...' {aka int ...}</code> so it seems <code>std::variant</code> is handling function signatures differently?</p>
  <p>I tried SFINAE but that does not seem to alleviate the problem</p>
  <pre class="lang-cpp prettyprint-override"><code>struct AllTypesOperatorOverload {
    template&lt;typename T, std::enable_if_t&lt;std::is_same&lt;T, int&gt;::value&gt;&gt;
    T operator()(const T &amp;data) {
      std::cout &lt;&lt; &quot;visiting int node&quot; &lt;&lt; std::endl;
      return data;
    }
    template&lt;typename T, std::enable_if_t&lt;std::is_same&lt;T, double&gt;::value&gt;&gt;
    T operator()(const T &amp;data) {
      std::cout &lt;&lt; &quot;visiting double node&quot; &lt;&lt; std::endl;
      return data;
    }
  };
  </code></pre>
  <p>This will now report an <code>error: no type named 'type' in 'struct std::invoke_result&lt;AllTypesOperatorOverload, int&amp;&gt;'</code>. Is there a way to provide <code>operator()</code> for all types and then receive their respective values into <code>bar</code> with the correct type depending on how <code>foo</code> has been set? I am aware of <code>std::get_if&lt;T&gt;()</code> which may be of use here, but ideally, I don't want to have a long if statement checking for each type, unless absolutely necessary (this is a simplified example, I may want to have several more types in my <code>std::variant</code>).</p>