<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[SFINAE in für mehrere Fälle in bestimmter Reihenfolge]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich habe folgendes Problem. Ich habe verschiedene Klassenhierarchien. Ich möchte eine bestimmte Information abfragen und im Prinzip kann ich diese auch bekommen. Leider wurde bei jeder Klasse eine andere Art der Implementierung gewählt und zudem unterstützen einige auch mehrere Arten...</p>
<p>Bei der einen Klassenhierarchie erhalte ich die gesuchte Information durch den Aufruf einer Member-Funktion, bei einer anderen durch eine freie Funktion und bei wieder anderen ist es eine statische Variable der Klasse.</p>
<p>Beispiel:</p>
<pre><code>struct A {}; std::string nameOfClass(const A &amp;);
struct B { char* className() const; };
struct C { static std::string className; };
</code></pre>
<p>Was ich zu implementieren Versuche:</p>
<pre><code>struct ClassNameGetter {
  template&lt;class T&gt;
  std::string className(const T &amp;obj) {
      return obj.className;
  }

  template&lt;class T&gt;
  std::string className(const T &amp;obj) {
      return obj.className();
  }

  template&lt;class T&gt;
  std::string className(const T &amp;obj) {
      return nameOfClass(obj);
  }
};
</code></pre>
<p>Klar, im letzten Beispiel fehlt jetzt SFINAE. Allerdings habe ich große Probleme damit und weiß nicht wie ich es implementieren muss.</p>
<p>Ich habe es mit std::enable_if und Templates wie diesem versucht:</p>
<pre><code>template&lt;typename C&gt;
class has_className_method {
private:
    template&lt;typename T&gt;
    static constexpr auto check(T*)
        -&gt; typename std::is_same&lt;decltype(std::declval&lt;T&gt;().className()), void&gt;::type;

    template&lt;typename&gt;
    static constexpr auto check(...)
        -&gt; std::false_type;

    typedef decltype(check&lt;C&gt;(0)) type;

public:
    static constexpr bool value = type::value;
};
</code></pre>
<p>Vergleichbares habe ich für alle drei Fälle implementiert und scheinbar funktionieren diese Templates auch. Allerdings weiß ich nicht, wie ich diese in der ClassNameGetter Klasse einsetzen muss.</p>
<p>Kann mir jemand helfen um auf die richtige Spur zu kommen?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/339218/sfinae-in-für-mehrere-fälle-in-bestimmter-reihenfolge</link><generator>RSS for Node</generator><lastBuildDate>Sun, 12 Apr 2026 09:30:10 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/339218.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 12 Aug 2016 21:02:48 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to SFINAE in für mehrere Fälle in bestimmter Reihenfolge on Fri, 12 Aug 2016 21:02:48 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich habe folgendes Problem. Ich habe verschiedene Klassenhierarchien. Ich möchte eine bestimmte Information abfragen und im Prinzip kann ich diese auch bekommen. Leider wurde bei jeder Klasse eine andere Art der Implementierung gewählt und zudem unterstützen einige auch mehrere Arten...</p>
<p>Bei der einen Klassenhierarchie erhalte ich die gesuchte Information durch den Aufruf einer Member-Funktion, bei einer anderen durch eine freie Funktion und bei wieder anderen ist es eine statische Variable der Klasse.</p>
<p>Beispiel:</p>
<pre><code>struct A {}; std::string nameOfClass(const A &amp;);
struct B { char* className() const; };
struct C { static std::string className; };
</code></pre>
<p>Was ich zu implementieren Versuche:</p>
<pre><code>struct ClassNameGetter {
  template&lt;class T&gt;
  std::string className(const T &amp;obj) {
      return obj.className;
  }

  template&lt;class T&gt;
  std::string className(const T &amp;obj) {
      return obj.className();
  }

  template&lt;class T&gt;
  std::string className(const T &amp;obj) {
      return nameOfClass(obj);
  }
};
</code></pre>
<p>Klar, im letzten Beispiel fehlt jetzt SFINAE. Allerdings habe ich große Probleme damit und weiß nicht wie ich es implementieren muss.</p>
<p>Ich habe es mit std::enable_if und Templates wie diesem versucht:</p>
<pre><code>template&lt;typename C&gt;
class has_className_method {
private:
    template&lt;typename T&gt;
    static constexpr auto check(T*)
        -&gt; typename std::is_same&lt;decltype(std::declval&lt;T&gt;().className()), void&gt;::type;

    template&lt;typename&gt;
    static constexpr auto check(...)
        -&gt; std::false_type;

    typedef decltype(check&lt;C&gt;(0)) type;

public:
    static constexpr bool value = type::value;
};
</code></pre>
<p>Vergleichbares habe ich für alle drei Fälle implementiert und scheinbar funktionieren diese Templates auch. Allerdings weiß ich nicht, wie ich diese in der ClassNameGetter Klasse einsetzen muss.</p>
<p>Kann mir jemand helfen um auf die richtige Spur zu kommen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2505320</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2505320</guid><dc:creator><![CDATA[Hilefoks]]></dc:creator><pubDate>Fri, 12 Aug 2016 21:02:48 GMT</pubDate></item><item><title><![CDATA[Reply to SFINAE in für mehrere Fälle in bestimmter Reihenfolge on Fri, 12 Aug 2016 21:24:37 GMT]]></title><description><![CDATA[<blockquote>
<p>Leider wurde bei jeder Klasse eine andere Art der Implementierung gewählt und zudem unterstützen einige auch mehrere Arten...</p>
</blockquote>
<p>Hier liegt der Knackpunkt; wir müssen eine Rangfolge wählen, anhand der in mehrdeutigen Fällen unterschieden wird.</p>
<p>Ungetestet - könnte etwa so aussehen:</p>
<pre><code>namespace detail {
  template &lt;int i&gt; struct rank : rank&lt;i+1&gt; {};
  template &lt;&gt; struct rank&lt;30&gt; {};

  template &lt;typename T&gt;
  auto getName(T const&amp; t, rank&lt;0&gt;) -&gt; decltype(t.className()) {
      return t.className(); }
  template &lt;typename T&gt;
  auto getName(T const&amp; t, rank&lt;1&gt;) -&gt; decltype(nameOfClass(t)) {
      return nameOfClass(t); }
  template &lt;typename T&gt;
  auto getName(T const&amp; t, rank&lt;2&gt;) -&gt; decltype(t.className) {
      return t.className; }
}

template &lt;typename T&gt;
auto getName(T const&amp; t) {return detail::getName(t, detail::rank&lt;0&gt;{});}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2505322</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2505322</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Fri, 12 Aug 2016 21:24:37 GMT</pubDate></item></channel></rss>