นี่คืออย่างน้อยหนึ่งกรณี:
struct foo {
template<class T>
operator T() const {
std::cout << sizeof(T) << "\n";
return {};
}
};
ถ้าคุณทำ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) );
ซึ่งเป็นที่ยอมรับต้องมีบิตเล่นกลเพิ่มเติมได้ที่: ตัวอย่างสด (ฉันต้องทำการส่งคืนการอนุมานให้ทำการตรวจสอบ SFINAE ของ F จากนั้นทำให้ F เป็น SFINAE ที่เป็นมิตรและฉันต้องบล็อก std :: initializer_list ในตัวดำเนินการ deduce_return_t T. )