<?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[Erhalten von Funktionszeiger mit und ohne &amp;amp;]]></title><description><![CDATA[<p>Hiho,</p>
<p>wenn ich eine einfache Funktion habe, kann ich die Adresse für einen Funktionszeiger ja einmal mit und einmal ohne dem Adressoperator erhalten</p>
<pre><code>void foo() { cout &lt;&lt; &quot;I am foo!&quot; &lt;&lt; std::endl; }

. . .

auto f1 = foo;
auto f2 = &amp;foo;
</code></pre>
<p>Gibt es bei den Varianten einen Unterschied? Ist beides ISO-konform?</p>
<p>Der Hintergrund meiner Frage ist folgender: ich habe eine Klasse, welche einen Handler als Template-Argument durch mehrere Methoden mit boost::bind &quot;durchschleift&quot;.</p>
<p>Rufe ich die Methode mit &quot;foo&quot; als Parameter auf, bekomme ich einen Compilefehler. Mache ich dasselbe mit &quot;&amp;foo&quot;, geht alles wunderbar. Das hat mich verwundert, daher die Frage, ob das &quot;&amp;&quot; einen Unterschied macht bei einfachen Funktionszeigern.</p>
<p>VG</p>
<p>Pellaeon</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/324903/erhalten-von-funktionszeiger-mit-und-ohne-amp</link><generator>RSS for Node</generator><lastBuildDate>Mon, 13 Jul 2026 07:58:33 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/324903.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 07 Apr 2014 13:26:20 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Erhalten von Funktionszeiger mit und ohne &amp;amp; on Mon, 07 Apr 2014 13:26:20 GMT]]></title><description><![CDATA[<p>Hiho,</p>
<p>wenn ich eine einfache Funktion habe, kann ich die Adresse für einen Funktionszeiger ja einmal mit und einmal ohne dem Adressoperator erhalten</p>
<pre><code>void foo() { cout &lt;&lt; &quot;I am foo!&quot; &lt;&lt; std::endl; }

. . .

auto f1 = foo;
auto f2 = &amp;foo;
</code></pre>
<p>Gibt es bei den Varianten einen Unterschied? Ist beides ISO-konform?</p>
<p>Der Hintergrund meiner Frage ist folgender: ich habe eine Klasse, welche einen Handler als Template-Argument durch mehrere Methoden mit boost::bind &quot;durchschleift&quot;.</p>
<p>Rufe ich die Methode mit &quot;foo&quot; als Parameter auf, bekomme ich einen Compilefehler. Mache ich dasselbe mit &quot;&amp;foo&quot;, geht alles wunderbar. Das hat mich verwundert, daher die Frage, ob das &quot;&amp;&quot; einen Unterschied macht bei einfachen Funktionszeigern.</p>
<p>VG</p>
<p>Pellaeon</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2393178</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2393178</guid><dc:creator><![CDATA[Pellaeon]]></dc:creator><pubDate>Mon, 07 Apr 2014 13:26:20 GMT</pubDate></item><item><title><![CDATA[Reply to Erhalten von Funktionszeiger mit und ohne &amp;amp; on Mon, 07 Apr 2014 14:05:21 GMT]]></title><description><![CDATA[<p>Es ist gleich und ISO-konform.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2393195</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2393195</guid><dc:creator><![CDATA[manni66]]></dc:creator><pubDate>Mon, 07 Apr 2014 14:05:21 GMT</pubDate></item><item><title><![CDATA[Reply to Erhalten von Funktionszeiger mit und ohne &amp;amp; on Mon, 07 Apr 2014 18:13:33 GMT]]></title><description><![CDATA[<p>Funktionen zerfallen, wie Arrays, automatisch in Zeiger. Implizit. Jedoch macht das den Funktionsnamen nicht zu einem Zeiger.</p>
<p>Der Typ vom Ausdruck &quot;foo&quot; ist nach wie vor <code>void()</code> . Natürlich kann aber ein Funktionsparameter nicht den Typ <code>void()</code> haben. Daher wird bei der Deduzierung der Template-Argumente einfach ein Zeiger daraus gemacht.</p>
<pre><code>template&lt;typename T1, typename T2&gt;
void f( T1, T2 )
{
	// Die Parameter können auch T1*, T2* sein
	static_assert( std::is_same&lt;T1, T2&gt;::value, &quot;&quot; );
}

int main()
{
	f( f&lt;int, int&gt;, 
	  &amp;f&lt;int, int&gt; );
}
</code></pre>
<p>Das hängt aber vom Funktionsparameter ab! Ist der nämlich eine Referenz, wird daraus:</p>
<pre><code>template&lt;typename T1, typename T2&gt;
void f( T1&amp;&amp;, T2&amp;&amp; )
{
	static_assert( std::is_same&lt;T1, T2&gt;::value, &quot;&quot; );
	// Schlägt fehl; T1 ist eine Referenz auf eine Funktion, während T2 ein Zeiger ... ist.
	// Damit hat der erste Parameter den Typ void(&amp;)(int&amp;&amp;, int&amp;&amp;)
	// während der zweite Parameter den Typ void(*&amp;&amp;)(int&amp;&amp;, int&amp;&amp;) hat - also eine Referenz auf den Zeiger.
}

int main()
{
	f( f&lt;int, int&gt;,
	  &amp;f&lt;int, int&gt; );
}
</code></pre>
<p>Ich nehme also an, dass die Funktionsparameter Referenzen sind, und daher Typen an Klassentemplates übergeben werden die nicht gespeichert werden können o.ä.<br />
Das kannst du möglicherweise verhindern, in dem du auf die entsprechenden Template-Argumente<a href="http://en.cppreference.com/w/cpp/types/decay" rel="nofollow"> <code>std::decay</code> </a>anwendest, welches automatisch function-to-pointer decays durchführt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2393240</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2393240</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Mon, 07 Apr 2014 18:13:33 GMT</pubDate></item><item><title><![CDATA[Reply to Erhalten von Funktionszeiger mit und ohne &amp;amp; on Thu, 10 Apr 2014 06:12:07 GMT]]></title><description><![CDATA[<p>Arcoth  schrieb:</p>
<blockquote>
<p>Ich nehme also an, dass die Funktionsparameter Referenzen sind</p>
</blockquote>
<p>Richtig. An sich möchte ich einen beliebigen Handler an einen boost-asio-Callback &quot;durchschleifen&quot;. Und dort soll der Nutzer eben wie er möchte bind-Objekte oder eben auch einfache FUnktionen übergeben können.</p>
<pre><code>/******************************************************************************/
/* adds a packet to the sending queue                                         */
/******************************************************************************/
template&lt;typename T&gt;
void putMessage(const CBasicMessage&amp; msg, T&amp;&amp; errorHandler)
{
	//we can't give msg to the lambda because the post call returns immediately before the invocation
	//therefore we create the packet here and copy it into the lambda, the packet itself contains a smart pointer to the buffer
	m_socket.get_io_service().post(boost::bind(&amp;CMessageChannel::putPacket&lt;T&gt;,
											   this,
											   Packet(msg.getMsgType(), msg.getLength(), boost::const_pointer_cast&lt;CBasicMessage::CByteBuffer&gt;(msg.getByteBuffer())),
											   errorHandler));
}
</code></pre>
<p>Für diese Methode gibt es noch eine zweite Variante, welche um boost::bind-Objekte ein boost::protect legt.</p>
<p>putPacket wird innerhalb des ioServices abgearbeitet und fügt das Paket in die Warteschlange hinzu:</p>
<pre><code>template&lt;typename T&gt;
void putPacket(Packet&amp; packet, T&amp; errorHandler)
{
	bool writeInProgess = !m_outgoing.empty();
	m_outgoing.push_back(std::move(packet));
	if (!writeInProgess)
	{
		startAsyncWrite(errorHandler);
	}
};
</code></pre>
<p>startAsyncWrite startet dann den Schreibvorgang und übergibt den Handler per bind mit an die Callback-Methode, welche boost asio dann aufruft:</p>
<pre><code>template&lt;typename T&gt;
void CMessageChannel::startAsyncWrite(T&amp;&amp; errorHandler)
{
	//fill buffer with header information
	auto&amp; packet = m_outgoing.front();
	m_headerOutBuffer.putInt(packet.size, 0);
	m_headerOutBuffer.putShort(packet.type, 4);

	//write it
	auto&amp; buf = m_headerOutBuffer.getBuffer();
	boost::asio::async_write(m_socket, boost::asio::buffer(buf.begin(),
														   buf.size()),
														   boost::bind(&amp;CMessageChannel::handleAsyncWriteHeader&lt;T&gt;, this, _1, _2, std::forward&lt;T&gt;(errorHandler)));
</code></pre>
<p>Und dabei tritt eben das oben genannte Problem auf.</p>
<p>VG</p>
<p>Pellaeon<br />
}</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2393765</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2393765</guid><dc:creator><![CDATA[Pellaeon]]></dc:creator><pubDate>Thu, 10 Apr 2014 06:12:07 GMT</pubDate></item></channel></rss>