<?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[Scope-Operator]]></title><description><![CDATA[<p>Hallo!</p>
<p>Ich habe eine Bibliothek von Windows auf Linux portiert und habe folgendes Problem (ich denke, dass es an dem Scope-Operator liegt):</p>
<p>Ich habe eine Template-Klasse, die folgendermaßen aufgebaut ist:</p>
<pre><code>template &lt;unsigned int val&gt;
class Derivation : public Base
{
public:
static unsigned int doSomething();

static unsigned int start()
{
return (Derivation&lt;val&gt;::doSomething);
}
};
</code></pre>
<p>Aufruf von Konstruktor der Klasse Derivation erfolgt davor natürlich.</p>
<p>Je nachdem, welchen Wert val besitzt, soll doSomething von Datei file_1.cpp oder file_2.cpp aufgerufen werden. Beide Dateien enthalten die gleiche Signatur, nur deren Funktion ist natürlich unterschiedlich!<br />
Bsp. der Implementation von doSomething() in file_1.cpp:</p>
<pre><code>template&lt;unsigned int val&gt;unsigned int Derivation::doSomething()
{
return 1;
}
</code></pre>
<p>Das Problem besteht darin, dass das Programm den Wert von val nicht korrekt unterscheidet, d.h. es ruft die Funktion doSomething aus der falschen Datei auf.</p>
<p>Liegt es am Scope-Operator? Auf Linux funktioniert dies, auf Windows dagegen nicht! Muss ich irgendwelche compiler-flags setzen?</p>
<p>Habe versucht, es so knapp wie möglich zusammen zufassen, daher bitte nicht auf Implementations-vollständigkeit achten!</p>
<p>Grüße Stefan</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/252003/scope-operator</link><generator>RSS for Node</generator><lastBuildDate>Sun, 13 Sep 2026 16:16:17 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/252003.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 13 Oct 2009 14:10:55 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Scope-Operator on Tue, 13 Oct 2009 14:10:55 GMT]]></title><description><![CDATA[<p>Hallo!</p>
<p>Ich habe eine Bibliothek von Windows auf Linux portiert und habe folgendes Problem (ich denke, dass es an dem Scope-Operator liegt):</p>
<p>Ich habe eine Template-Klasse, die folgendermaßen aufgebaut ist:</p>
<pre><code>template &lt;unsigned int val&gt;
class Derivation : public Base
{
public:
static unsigned int doSomething();

static unsigned int start()
{
return (Derivation&lt;val&gt;::doSomething);
}
};
</code></pre>
<p>Aufruf von Konstruktor der Klasse Derivation erfolgt davor natürlich.</p>
<p>Je nachdem, welchen Wert val besitzt, soll doSomething von Datei file_1.cpp oder file_2.cpp aufgerufen werden. Beide Dateien enthalten die gleiche Signatur, nur deren Funktion ist natürlich unterschiedlich!<br />
Bsp. der Implementation von doSomething() in file_1.cpp:</p>
<pre><code>template&lt;unsigned int val&gt;unsigned int Derivation::doSomething()
{
return 1;
}
</code></pre>
<p>Das Problem besteht darin, dass das Programm den Wert von val nicht korrekt unterscheidet, d.h. es ruft die Funktion doSomething aus der falschen Datei auf.</p>
<p>Liegt es am Scope-Operator? Auf Linux funktioniert dies, auf Windows dagegen nicht! Muss ich irgendwelche compiler-flags setzen?</p>
<p>Habe versucht, es so knapp wie möglich zusammen zufassen, daher bitte nicht auf Implementations-vollständigkeit achten!</p>
<p>Grüße Stefan</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1792010</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1792010</guid><dc:creator><![CDATA[piwi133]]></dc:creator><pubDate>Tue, 13 Oct 2009 14:10:55 GMT</pubDate></item><item><title><![CDATA[Reply to Scope-Operator on Tue, 13 Oct 2009 14:35:08 GMT]]></title><description><![CDATA[<p>piwi133 schrieb:</p>
<blockquote>
<p>Habe versucht, es so knapp wie möglich zusammen zufassen, daher bitte nicht auf Implementations-vollständigkeit achten!</p>
</blockquote>
<p>Gerade das wäre aber interessant, wie hast du die Unterscheidung denn gemacht? Templatespezialisierung? Zeig einfach mal ein funktionierendes (bzw. nicht funktionierendes) Minimalbeispiel für dein Problem.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1792022</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1792022</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Tue, 13 Oct 2009 14:35:08 GMT</pubDate></item><item><title><![CDATA[Reply to Scope-Operator on Tue, 13 Oct 2009 14:59:36 GMT]]></title><description><![CDATA[<p>Die Unterscheidung besteht darin, dass je nach Wert von val der Konstruktor von Derivation mit dem Wert aufgerufen wird:</p>
<pre><code>template&lt;unsigned int val&gt;inline Derivation&lt;val&gt;::Derivation(unsigned int foo):Base(foo){}
</code></pre>
<p>also:</p>
<pre><code>AutoPtr&lt;Base&gt; Base::build (unsigned int foo)
{
AutoPtr&lt;Base&gt; ap(new Derivation&lt;133&gt;(foo));
}
</code></pre>
<p>AutoPtr ist ein weiterer Teil der Bibliothek, foo einfach ein Übergabewert</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1792039</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1792039</guid><dc:creator><![CDATA[piwi133]]></dc:creator><pubDate>Tue, 13 Oct 2009 14:59:36 GMT</pubDate></item><item><title><![CDATA[Reply to Scope-Operator on Tue, 13 Oct 2009 15:37:08 GMT]]></title><description><![CDATA[<p>piwi133 schrieb:</p>
<blockquote>
<p>Je nachdem, welchen Wert val besitzt, soll doSomething von Datei file_1.cpp oder file_2.cpp aufgerufen werden. Beide Dateien enthalten die gleiche Signatur, nur deren Funktion ist natürlich unterschiedlich!</p>
</blockquote>
<p>Das verstehe ich nicht ganz. Was meinst du mit Dateisignatur (sollte das Funktionssignatur heissen?), und inwiefern unterscheiden sich die Funktionen? Nur in ihrer internen Implementierung?</p>
<p>Sind die Konstruktoren Teile unterschiedlicher Templatespezialisierungen? Wenn nicht, wieso willst du überhaupt zwischen verschiedenen Konstruktoren auswählen? Ich wäre froh um ein etwas ausführlicheres Codestück, das vor allem die Unterschiede der Funktionen in Abhängigkeit der Templateparameter aufzeigt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1792061</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1792061</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Tue, 13 Oct 2009 15:37:08 GMT</pubDate></item><item><title><![CDATA[Reply to Scope-Operator on Tue, 13 Oct 2009 15:39:04 GMT]]></title><description><![CDATA[<p>Fehlen da vielleicht die Klammern hinter Derivation&lt;val&gt; :: doSomething**()** ?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1792063</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1792063</guid><dc:creator><![CDATA[DocShoe]]></dc:creator><pubDate>Tue, 13 Oct 2009 15:39:04 GMT</pubDate></item><item><title><![CDATA[Reply to Scope-Operator on Tue, 13 Oct 2009 15:43:49 GMT]]></title><description><![CDATA[<p>DocShoe schrieb:</p>
<blockquote>
<p>Fehlen da vielleicht die Klammern hinter Derivation&lt;val&gt; :: doSomething**()** ?</p>
</blockquote>
<p>Ich glaube eher, das ist ein Flüchtigkeitsfehler. Beispielsweise hat piwi133 bei der <code>Base::build()</code> -Funktion auch vergessen, einen Wert zurückzugeben. Zudem würde mich wundern, wenn das so auf Linux kompiliert werden konnte.</p>
<p>piwi133, ich fände es trotzdem gut, du könntest dich auf solche Dinge etwas achten, das erspart auch wilde Spekulationen. Am besten wäre ein kleines, aber vollständiges und vor allem korrektes Codebeispiel, das deine Problematik verdeutlicht. Und nimm vielleicht lieber die [cpp]- anstelle der [code]-Tags, das ist übersichtlicher. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1792066</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1792066</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Tue, 13 Oct 2009 15:43:49 GMT</pubDate></item><item><title><![CDATA[Reply to Scope-Operator on Tue, 13 Oct 2009 15:46:43 GMT]]></title><description><![CDATA[<p>Unterschiedliche Implementationen der gleichen Memberfunktion in verschiedenen ÜEs?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1792068</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1792068</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Tue, 13 Oct 2009 15:46:43 GMT</pubDate></item><item><title><![CDATA[Reply to Scope-Operator on Thu, 15 Oct 2009 10:53:01 GMT]]></title><description><![CDATA[<p>so, also hier nochmal alles mit Originalquelltext (wie gesagt, es handelt sich dabei um eine riesige Bibliothek):</p>
<p>Aufruf der Fkt. im Startprogramm:</p>
<pre><code class="language-cpp">AutoPtr&lt;FEBase&gt; fe (FEBase::build(dim, fe_type));
</code></pre>
<p>Implementierung von Fkt. build(nur relevanter switch-case):</p>
<pre><code class="language-cpp">AutoPtr&lt;FEBase&gt; FEBase::build (const unsigned int dim, const FEType&amp; fet)
{
    switch (dim)
    {
        case 2:
      {
        case LAGRANGE:
	    {
	      AutoPtr&lt;FEBase&gt; ap(new FE&lt;2,LAGRANGE&gt;(fet));
	      return ap;
	    }
     }
    }
}
</code></pre>
<p>Konstruktor von Klasse FE:</p>
<pre><code class="language-cpp">template &lt;unsigned int Dim, FEFamily T&gt;
inline
FE&lt;Dim,T&gt;::FE (const FEType&amp; fet) :
  FEBase (Dim,fet),
  last_side(libMesh::invalid_uint),
  last_edge(libMesh::invalid_uint)
{
  libmesh_assert (T == fe_type.family);
}
</code></pre>
<p>später im Startprogramm erfolgt er Aufruf von fe-&gt;reinit(). Darin wird die Funktion n_shape_functions() aufgerufen, die folgendermaßen in fe.h (Klasse FE) implementiert ist:</p>
<pre><code class="language-cpp">static unsigned int n_shape_functions (const ElemType t, const Order o)
  {
	return (FE&lt;Dim,T&gt;::n_dofs (t,o));
  }
</code></pre>
<p>Und genau dieser Aufruf ist das Problem. Der Wert von T ist 0, es wird aber immer die Funktion von Wert 5 aufgerufen!<br />
Diese heißt beiden Fällen n_dofs() und enthält die gleiche Signatur, ist aber in unterschiedliche .cpp-files implementiert.</p>
<p>Deklariert wird sie in Klasse FE folgendermaßen:</p>
<pre><code class="language-cpp">static unsigned int n_dofs(const ElemType t, const Order o);
</code></pre>
<p>Ich hoffe, dass es nun etwas besser verständlich ist!</p>
<p>Grüße<br />
Stefan</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1792840</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1792840</guid><dc:creator><![CDATA[piwi133]]></dc:creator><pubDate>Thu, 15 Oct 2009 10:53:01 GMT</pubDate></item><item><title><![CDATA[Reply to Scope-Operator on Thu, 15 Oct 2009 11:13:04 GMT]]></title><description><![CDATA[<p>piwi133 schrieb:</p>
<blockquote>
<p>Und genau dieser Aufruf ist das Problem. Der Wert von T ist 0, es wird aber immer die Funktion von Wert 5 aufgerufen!<br />
Diese heißt beiden Fällen n_dofs() und enthält die gleiche Signatur, ist aber in unterschiedliche .cpp-files implementiert.</p>
<p>Deklariert wird sie in Klasse FE folgendermaßen:</p>
<pre><code class="language-cpp">static unsigned int n_dofs(const ElemType t, const Order o);
</code></pre>
</blockquote>
<p>Und diese Definitionen sehen wie aus (der eigentliche Funktionskörper allerdings interessiert nicht)?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1792846</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1792846</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Thu, 15 Oct 2009 11:13:04 GMT</pubDate></item><item><title><![CDATA[Reply to Scope-Operator on Thu, 15 Oct 2009 11:17:57 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">template &lt;unsigned int Dim, FEFamily T&gt;
unsigned int FE&lt;Dim,T&gt;::n_dofs(const ElemType t, const Order o)
{}
</code></pre>
<p>FEFamily ist nur ein enum.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1792849</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1792849</guid><dc:creator><![CDATA[piwi133]]></dc:creator><pubDate>Thu, 15 Oct 2009 11:17:57 GMT</pubDate></item><item><title><![CDATA[Reply to Scope-Operator on Thu, 15 Oct 2009 11:31:09 GMT]]></title><description><![CDATA[<p>Welche Spezialisierung wird wo und in welcher ÜE instantiiert? Technisch gesehen wird hier bereits die ODR verletzt, wenn die Definitionen in den verschiedenen ÜEs verschieden sind.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1792853</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1792853</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Thu, 15 Oct 2009 11:31:09 GMT</pubDate></item><item><title><![CDATA[Reply to Scope-Operator on Thu, 15 Oct 2009 11:56:34 GMT]]></title><description><![CDATA[<p>in extra Datei (fe_macro.h):</p>
<pre><code class="language-cpp">#define INSTANTIATE_FE(_dim)   template class FE&lt; (_dim), CLOUGH&gt;; \
                               template class FE&lt; (_dim), HERMITE&gt;;    \
                               template class FE&lt; (_dim), HIERARCHIC&gt;;   \
                               template class FE&lt; (_dim), LAGRANGE&gt;;   \
                               template class FE&lt; (_dim), MONOMIAL&gt;;   \
                               template class FE&lt; (_dim), BERNSTEIN&gt;;     \
                               template class FE&lt; (_dim), SZABAB&gt;;     \
                               template class FE&lt; (_dim), XYZ&gt;

#define INSTANTIATE_MBRF(_dim,_t) \
  template unsigned int FE&lt;_dim,_t&gt;::n_dofs_at_node(ElemType,Order,unsigned int);
#endif
</code></pre>
<p>in Funktion fe.c:</p>
<pre><code class="language-cpp">INSTANTIATE_FE(1);
INSTANTIATE_FE(2);
INSTANTIATE_FE(3);
</code></pre>
<p>und in den unterschiedlichen .cpp-Files (hier z.B. fe_lagrange.cpp):</p>
<pre><code class="language-cpp">// Explicit instantiation of member functions
INSTANTIATE_MBRF(1,LAGRANGE);
INSTANTIATE_MBRF(2,LAGRANGE);
INSTANTIATE_MBRF(3,LAGRANGE);
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1792859</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1792859</guid><dc:creator><![CDATA[piwi133]]></dc:creator><pubDate>Thu, 15 Oct 2009 11:56:34 GMT</pubDate></item><item><title><![CDATA[Reply to Scope-Operator on Thu, 15 Oct 2009 13:09:57 GMT]]></title><description><![CDATA[<p>Zusammengefasst sieht das also ungefähr so aus?</p>
<pre><code class="language-cpp">// header.h

enum my_enum { my_enum1, my_enum2 };

template &lt;unsigned Dim, my_enum T&gt;
class X
{
...
    static unsigned n_dofs(Foo x, Bar y);
...
};

//ÜE1.cpp
include &quot;header.h&quot;
// definiere Member von X außer n_dofs
...
// instantiiere explizit:
template class X&lt;1,my_enum1&gt;;
template class X&lt;1,my_enum2&gt;;
template class X&lt;2,my_enum1&gt;;
template class X&lt;2,my_enum2&gt;;

//ÜE2.cpp
include &quot;header.h&quot;

template &lt;unsigned Dim, my_enum T&gt;
unsigned X&lt;Dim,T&gt;::n_dofs(Foo x, Bar y) { do_something1(); }

template X&lt;1,my_enum1&gt;::n_dofs;
template X&lt;2,my_enum1&gt;::n_dofs;

//ÜE3.cpp
include &quot;header.h&quot;

template &lt;unsigned Dim, my_enum T&gt;
unsigned X&lt;Dim,T&gt;::n_dofs(Foo x, Bar y) { do_something2(); }

template X&lt;1,my_enum2&gt;::n_dofs;
template X&lt;2,my_enum2&gt;::n_dofs;
</code></pre>
<p>Das verletzt, wie gesagt, die ODR. Man kann sich vorstellen, vorausgesetzt, es finden keine impliziten Instantiierungen statt. Das ist allerdings eine Bedingung auf man das Design niemals aufbauen sollte (das Hinzufügen einer Komponente kann zum Zusammenbruch führen, ohne dass sich das beim Compilieren/Linken bemerkbar macht).</p>
<p>Richtig wäre, hier von vornherein nur die Spezialisierungen zu definieren, die auch instantiiert werden sollen/müssen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1792899</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1792899</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Thu, 15 Oct 2009 13:09:57 GMT</pubDate></item><item><title><![CDATA[Reply to Scope-Operator on Tue, 03 Nov 2009 14:08:57 GMT]]></title><description><![CDATA[<p>so, habe mich nochmals um das Problem gekümmert!<br />
Habe ein kleines Testprogramm geschrieben und siehe da, es funktioniert einwandfrei!</p>
<p>Hier das Prog:</p>
<p>main.C</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &quot;fe.h&quot;

using namespace std;

int main()
{
	FE&lt;2,LAGRANGE&gt; fe; //oder FE&lt;2,XYZ&gt; fe;
	unsigned int ret=fe.n_sf(QUAD9);
	cout &lt;&lt; &quot;Family: &quot; &lt;&lt; ret &lt;&lt; endl;
	return 0;
}
</code></pre>
<p>fe.h</p>
<pre><code class="language-cpp">#ifndef __FE_H
#define __FE_H

#include &lt;iostream&gt;
#include &quot;macro_elem.h&quot;
#include &quot;enum.h&quot;

template &lt;unsigned int Dim, FEFamily T&gt;
class FE
{
	public:
		FE();
		static unsigned int n_dofs(ElemType);
		unsigned int n_sf(ElemType val)
		{
			unsigned int tmp=1;
			tmp = FE&lt;Dim,T&gt;::n_dofs(val);
			return tmp;
		}
};

template &lt;unsigned int Dim, FEFamily T&gt;
inline
FE&lt;Dim,T&gt;::FE ()
{
	printf(&quot;Im FE-constructor\n&quot;);
}

#endif
</code></pre>
<p>fe.C</p>
<pre><code class="language-cpp">#include &quot;fe.h&quot;
#include &quot;macro.h&quot;

INSTANTIATE_FE(2);
</code></pre>
<p>fe_lag.C</p>
<pre><code class="language-cpp">#include &quot;fe.h&quot;
#include &quot;macro.h&quot;

template &lt;unsigned int Dim, FEFamily T&gt;
unsigned int FE&lt;Dim,T&gt;::n_dofs(ElemType val)
{
	printf(&quot;Ich bin in Lagrange :-)\nElem: %d\n&quot;,val);
	return 0;
}

INSTANTIATE_MBRF(2,LAGRANGE);
</code></pre>
<pre><code class="language-cpp">#include &quot;fe.h&quot;
#include &quot;macro.h&quot;

template &lt;unsigned int Dim, FEFamily T&gt;
unsigned int FE&lt;Dim,T&gt;::n_dofs(ElemType val)
{
	printf(&quot;Ich bin in X :-(\nElem: %d\n&quot;,val);
	return 5;
}

INSTANTIATE_MBRF(2,XYZ);
</code></pre>
<p>macro.h</p>
<pre><code class="language-cpp">#ifndef __MACRO_H
#define __MACRO_H

#define INSTANTIATE_FE(_dim) template class FE&lt; (_dim), LAGRANGE&gt;;     \
                             template class FE&lt; (_dim), XYZ&gt;

#define INSTANTIATE_MBRF(_dim,_t) \
							template unsigned int FE&lt;_dim,_t&gt;::n_dofs(ElemType)

#endif
</code></pre>
<p>enum.h</p>
<pre><code class="language-cpp">#ifndef __ENUM_H
#define __ENUM_H

enum FEFamily
{
	LAGRANGE=0,
	XYZ=5
};

#endif
</code></pre>
<p>macro_elem.h</p>
<pre><code class="language-cpp">#ifndef __MACRO_EELEM_H
#define __MACRO_EELEM_H

enum ElemType
{
	QUAD9=9
};

#endif
</code></pre>
<p>Verletzt dies die ODR?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1802671</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1802671</guid><dc:creator><![CDATA[piwi133]]></dc:creator><pubDate>Tue, 03 Nov 2009 14:08:57 GMT</pubDate></item></channel></rss>