C++ में टाइप इंफॉर्मेशन बैकवर्ड फ्लो कब करती है?




types language-lawyer (2)

मैंने अभी-अभी Stephan T. Lavavej को CppCon 2018 में "क्लास टेम्प्लेट आर्ग्युमेंट CppCon 2018 " पर बात करते हुए देखा, जहाँ कुछ बिंदु पर वह संयोग से कहता है:

C ++ प्रकार की जानकारी में लगभग कभी भी पीछे की ओर नहीं बहती है ... मुझे "लगभग" कहना पड़ा क्योंकि एक या दो मामले हैं, संभवतः अधिक लेकिन बहुत कम

यह जानने की कोशिश करने के बावजूद कि वह किन मामलों का हवाला दे रहा है, मैं कुछ भी नहीं कर सकता। इसलिए सवाल:

जिन मामलों में C ++ 17 मानक जनादेश देते हैं, वे किस प्रकार की सूचना को पीछे की ओर फैलाते हैं?


मेरा मानना ​​है कि अतिभारित कार्यों की स्थिर कास्टिंग में प्रवाह विपरीत दिशा में जाता है जैसा कि सामान्य अधिभार संकल्प में होता है। तो उनमें से एक पीछे की तरफ है, मुझे लगता है।


यहाँ कम से कम एक मामला है:

struct foo {
  template<class T>
  operator T() const {
    std::cout << sizeof(T) << "\n";
    return {};
  }
};

यदि आप foo f; int x = f; double y = f; foo f; int x = f; double y = f; , टाइप जानकारी "पीछे की ओर" बह जाएगा यह पता लगाने के लिए कि T operator T में क्या है।

आप इसे और अधिक उन्नत तरीके से उपयोग कर सकते हैं:

template<class T>
struct tag_t {using type=T;};

template<class F>
struct deduce_return_t {
  F f;
  template<class T>
  operator T()&&{ return std::forward<F>(f)(tag_t<T>{}); }
};
template<class F>
deduce_return_t(F&&)->deduce_return_t<F>;

template<class...Args>
auto construct_from( Args&&... args ) {
  return deduce_return_t{ [&](auto ret){
    using R=typename decltype(ret)::type;
    return R{ std::forward<Args>(args)... };
  }};
}

तो अब मैं कर सकता हूँ

std::vector<int> v = construct_from( 1, 2, 3 );

और यह काम करता है।

बेशक, सिर्फ {1,2,3} क्यों नहीं? खैर, {1,2,3} कोई अभिव्यक्ति नहीं है।

std::vector<std::vector<int>> v;
v.emplace_back( construct_from(1,2,3) );

जो, माना जाता है, थोड़ा और अधिक आवश्यक है: लाइव उदाहरण । (मुझे कटौती की वापसी F की SFINAE जांच करनी है, तो F को SFINAE के अनुकूल बनाएं, और मुझे std :: initializer_list in deduce_return_t ऑपरेटर T. में ब्लॉक करना होगा)







type-deduction