<?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[Falsches Template wird genutzt]]></title><description><![CDATA[<p>Hallo,<br />
für eine Art Container habe ich eine Template-Klasse geschrieben, die unter anderem einen Konstruktor hat, der die Elemente direkt übergeben bekommt (siehe <a href="http://www.c-plusplus.net/forum/p2289416#2289416" rel="nofollow">http://www.c-plusplus.net/forum/p2289416#2289416</a>), und einen, der mit zwei Iteratoren die Daten ausfüllt.<br />
Wenn ich allerdings einen Container der Größe 2 erstelle, möchte der Compiler <strong>immer</strong> die Iterator-Variante verwenden, was dann z.B. dazu führt, dass er sich kurz danach beschwert, dass mein Template-Parameter doch gar keinen operator* unterstützt.<br />
Gibt es da eine Möglichkeit, das zu ändern, oder kann ich nur einen der beiden Konstruktoren haben?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/312797/falsches-template-wird-genutzt</link><generator>RSS for Node</generator><lastBuildDate>Sun, 02 Aug 2026 17:50:39 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/312797.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 14 Jan 2013 15:15:20 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Falsches Template wird genutzt on Mon, 14 Jan 2013 15:15:20 GMT]]></title><description><![CDATA[<p>Hallo,<br />
für eine Art Container habe ich eine Template-Klasse geschrieben, die unter anderem einen Konstruktor hat, der die Elemente direkt übergeben bekommt (siehe <a href="http://www.c-plusplus.net/forum/p2289416#2289416" rel="nofollow">http://www.c-plusplus.net/forum/p2289416#2289416</a>), und einen, der mit zwei Iteratoren die Daten ausfüllt.<br />
Wenn ich allerdings einen Container der Größe 2 erstelle, möchte der Compiler <strong>immer</strong> die Iterator-Variante verwenden, was dann z.B. dazu führt, dass er sich kurz danach beschwert, dass mein Template-Parameter doch gar keinen operator* unterstützt.<br />
Gibt es da eine Möglichkeit, das zu ändern, oder kann ich nur einen der beiden Konstruktoren haben?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2289598</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2289598</guid><dc:creator><![CDATA[Wurstinator]]></dc:creator><pubDate>Mon, 14 Jan 2013 15:15:20 GMT</pubDate></item><item><title><![CDATA[Reply to Falsches Template wird genutzt on Mon, 14 Jan 2013 15:18:46 GMT]]></title><description><![CDATA[<p>Nimm lieber eine <code>std::initializer_list&lt;T&gt;</code> , dann kannst du zwischen den Konstruktoren auswählen (() vs. {})</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2289602</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2289602</guid><dc:creator><![CDATA[inili]]></dc:creator><pubDate>Mon, 14 Jan 2013 15:18:46 GMT</pubDate></item><item><title><![CDATA[Reply to Falsches Template wird genutzt on Mon, 14 Jan 2013 15:19:55 GMT]]></title><description><![CDATA[<p>Wurstinator schrieb:</p>
<blockquote>
<p>Gibt es da eine Möglichkeit, das zu ändern, oder kann ich nur einen der beiden Konstruktoren haben?</p>
</blockquote>
<p>Sicher. Zeig erst mal was du hast.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2289603</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2289603</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Mon, 14 Jan 2013 15:19:55 GMT</pubDate></item><item><title><![CDATA[Reply to Falsches Template wird genutzt on Mon, 14 Jan 2013 16:27:25 GMT]]></title><description><![CDATA[<p>@ inili: Tut mir Leid, das verstehe ich nicht wirklich. Meinst du, der Iterator-Konstruktor soll bleiben und den anderen soll ich zur initializer_list ändern?</p>
<p>@ camper:</p>
<pre><code>#ifndef INCLUDE_REALVECTOR_H
#define INCLUDE_REALVECTOR_H

#include &lt;array&gt;
#include &lt;utility&gt;

template &lt;unsigned int N&gt;
class RealVector
{
    public:
        RealVector();
        template &lt;typename InputIter&gt; 
            RealVector(InputIter first, InputIter last);
        template &lt;typename... Args&gt;
            RealVector(Args... args);
    private:
        std::array&lt;double, N&gt; numbers;
};

template &lt;typename... T&gt; struct allSame; 
template &lt;&gt; struct allSame&lt;&gt; 
    : std::true_type {}; 
template &lt;typename T, typename... U&gt; struct allSame&lt;T, U...&gt; 
    : std::is_same&lt;allSame&lt;T, U...&gt;, allSame&lt;U..., T&gt;&gt; {}; 

template &lt;typename T, typename... U&gt; struct canConvert
    : allSame&lt; std::true_type , typename std::is_convertible&lt;U, T&gt;::type... &gt; {};

#include &quot;realvector.impl&quot;

#endif
</code></pre>
<pre><code>#include &lt;iterator&gt;

template &lt;unsigned int N&gt;
RealVector&lt;N&gt;::RealVector()
{}

template &lt;unsigned int N&gt;
template &lt;typename InputIter&gt;
RealVector&lt;N&gt;::RealVector(InputIter first, InputIter last)
{
    typedef std::iterator_traits&lt;InputIter&gt;::iterator_category iter_cat;
    static_assert( std::is_base_of&lt;std::input_iterator_tag, iter_cat&gt;::value ,
                   &quot;iterator must be of type InputIterator&quot; );
    int n = 0;
    while (n &lt; N &amp;&amp; first != last)
        numbers[n] = *first++;
}

template &lt;unsigned int N&gt;
template &lt;typename... Args&gt;
RealVector&lt;N&gt;::RealVector(Args... args)
    : numbers({{args...}})
{
    static_assert( sizeof...(args) == N , &quot;wrong number of arguments&quot; );
    static_assert( canConvert&lt;double, Args...&gt;::value , &quot;arguments have to be of type double&quot; );
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2289622</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2289622</guid><dc:creator><![CDATA[Wurstinator]]></dc:creator><pubDate>Mon, 14 Jan 2013 16:27:25 GMT</pubDate></item><item><title><![CDATA[Reply to Falsches Template wird genutzt on Mon, 14 Jan 2013 16:47:00 GMT]]></title><description><![CDATA[<p>Genau, so meine ich das.</p>
<pre><code class="language-cpp">template &lt;unsigned int N&gt;
struct RealVector {
  RealVector();
  template &lt;typename InputIter&gt; RealVector(InputIter first, InputIter last);
  RealVector(std::initializer_list&lt;double&gt; inili) {
    assert(inili.size() == N);
    ...
  }
};

int main()
{
  RealVector&lt;2&gt; r1; // default ctor
  std::array&lt;int, 4&gt; arr{1,2,3,4};
  RealVector&lt;2&gt; r2(arr.begin(), arr.end()); // iterator ctor
  RealVector&lt;2&gt; r3{1,2}; // initializer list

  RealVector&lt;7&gt; r4{1,2,3,4,5,6,7}; // initializer list
}
</code></pre>
<p>In deinem Fall (wenn die Elemente vom Typ double sind) kann man beim Iteratorenkonstruktor natürlich auf die Existenz des Dereferenzierungsoperators testen, aber das halte ich nicht für eine gute Idee. Die Initializerlist ist genau für solche Fälle da.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2289623</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2289623</guid><dc:creator><![CDATA[inili]]></dc:creator><pubDate>Mon, 14 Jan 2013 16:47:00 GMT</pubDate></item><item><title><![CDATA[Reply to Falsches Template wird genutzt on Mon, 14 Jan 2013 18:51:08 GMT]]></title><description><![CDATA[<p>Eine bisschen SFINAE hilft. initializer_list mag ich nicht.<br />
Die fehlende Überprüfung der Größe bereits beim Compilieren machen diese hier unattraktiv. Zudem wird damit der falsche Konstruktor repariert.<br />
Und die Tatsache, dass die Klammerwahl eine Rolle spielen kann, spricht auch dagegen, diese Art Subtilität halte ich für einen schweren Fehler des Standardkomitees.</p>
<pre><code class="language-cpp">template &lt;unsigned int N&gt;
class RealVector
{
    public:
        RealVector();
        template &lt;typename InputIter, typename std::enable_if&lt;std::is_convertible&lt;typename std::iterator_traits&lt;InputIter&gt;::type, double&gt;::value
            &amp;&amp; std::is_base_of&lt;std::input_iterator_tag, typename std::iterator_traits&lt;InputIter&gt;::type&gt;::value, int&gt;::type = 0&gt;
            RealVector(InputIter first, InputIter last);
        template &lt;typename... Args&gt;
            RealVector(Args... args);
    private:
        std::array&lt;double, N&gt; numbers;
};

template &lt;unsigned int N&gt;
template &lt;typename InputIter, typename std::enable_if&lt;std::is_convertible&lt;typename std::iterator_traits&lt;InputIter&gt;::type, double&gt;::value
    &amp;&amp; std::is_base_of&lt;std::input_iterator_tag, typename std::iterator_traits&lt;InputIter&gt;::type&gt;::value, int&gt;::type&gt;
RealVector&lt;N&gt;::RealVector(InputIter first, InputIter last)
{
    typedef typename std::iterator_traits&lt;InputIter&gt;::iterator_category iter_cat;
    static_assert( std::is_base_of&lt;std::input_iterator_tag, iter_cat&gt;::value ,
                   &quot;iterator must be of type InputIterator&quot; );
    int n = 0;
    while (n &lt; N &amp;&amp; first != last)
        numbers[n] = *first++;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2289647</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2289647</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Mon, 14 Jan 2013 18:51:08 GMT</pubDate></item><item><title><![CDATA[Reply to Falsches Template wird genutzt on Mon, 14 Jan 2013 20:27:12 GMT]]></title><description><![CDATA[<p>@ inili: Ich mag initializer_lists nicht und benutze sie daher ungerne, da sie nichts Konstruktives bringen (in diesem Fall) und ungewöhnliche Syntax haben.</p>
<p>@ camper: Wenn ich also auf std::enable_if&lt;...&gt;::type zugreife, dieser aber nicht existiert, schlägt das Template sozusagen fehl?</p>
<p>edit:<br />
Gibt es eigentlich eine Möglichkeit, den Test von enable_if auszulagenr, damit es übersichtlicher wird?</p>
<pre><code>template &lt;typename Iter&gt; struct isInputIter
    : std::is_base_of&lt;std::input_iterator_tag, typename std::iterator_traits&lt;Iter&gt;::iterator_category&gt; {};
</code></pre>
<p>Sowas in der Art. Aber wenn ich das dann einfüge, tritt wieder das alte Problem auf, dass der Compiler versucht, die Zahlen als Iterator zu interpretieren. Ergo sagt er mir, dass double keinen Member namens iterator_category hat.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2289660</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2289660</guid><dc:creator><![CDATA[Wurstinator]]></dc:creator><pubDate>Mon, 14 Jan 2013 20:27:12 GMT</pubDate></item></channel></rss>