std::forward
'u öğreniyorum.Neden C++ dizeleri std :: forward işlevini çağırmak istemiyor?
#include <iostream>
#include <typeinfo>
#include <string>
using namespace std;
class Example {
};
ostream &operator << (ostream &os, const Example &e) { os << "yes!"; return os; }
void test_forward_inner(const Example &e) { cout << "& " << e << endl; }
void test_forward_inner(Example &&e) { cout << "&& " << e << endl; }
void test_forward_inner(const string &e) { cout << "& " << e << endl; }
void test_forward_inner(string &&e) { cout << "&& " << e << endl; }
template <typename T>
void test_forward_wrapper(T &&arg) {
test_forward_inner(arg);
}
int main()
{
Example e;
test_forward_wrapper(e);
test_forward_wrapper(Example());
cout << endl;
string s("hello");
test_forward_wrapper(s);
test_forward_wrapper("hello");
return 0;
}
ben test_forward_wrapper()
den test_forward_inner()
bir lvalue ve rvalue iletmek için çalıştı: Bence başka işlev çağrısına argümanları yönlendirmeden önce std::forward
demiyorlar ne olacağını test etmek için küçük bir program yazdım. Bu program çalıştırıldığında çıktısı verir:
& example
& example
& hello
&& hello
std::string
için s, istenen iç işlev çağrıldı fakat kendi sınıf için sadece lvalue versiyonu olarak adlandırıldı. Yalnızca argümanları iç işleve iletmeden önce std::forward
'u çağırırsam, rvalue sürümünün çağrılması mümkündür.
Farkı burada yapan nedir? Bildiğim gibi, referans daraltma kurallarına göre, sarıcı Example()
ile çağrıldığında, bir rengin, T
Example
ve arg
türünün Example &&
türüne sahip olması, böylece iç işlevin rengin versiyonunun çağrılması gerekir.
Ve burada std::string
durumu gibi diğer durumlar için iç işlevin doğru sürümü çağrıldı, ardından std::forward
buradan çıkarılabilir mi? Eğer değilse, ne (belki de kötü bir şey) olur?
önemli bir kısmı, iç fonksiyonu sadece 'string' oluşur' dönüşüm anlamına std :: string', kabulü, değil ise sargı, (böylece zorlama aramayýn meydana gelir) şablonu olmasıdır daha sonra (iç işleve bir r-değeri referansı sağlar), iletme söz konusu değildir. – ShadowRanger
'' merhaba '' 'const char *' değil, 'const char *' haline dönüşebilen bir 'const char [6]' dır. . –
^(ve bu durumda çürümez) –