का व्यवहार बदलता है मैंने header for optionally-lazy parameters बनाया है (GitHub repository में भी दिखाई देता है)। (यह not my first question based on the header है।)वर्चुअल विनाशक decltype
मेरे पास बेस-क्लास टेम्पलेट और दो व्युत्पन्न-श्रेणी टेम्पलेट्स हैं। बेस-क्लास टेम्पलेट में के साथ protected
कन्स्ट्रक्टर है। इस कन्स्ट्रक्टर को केवल एक विशेष व्युत्पन्न-वर्ग द्वारा बुलाया जाता है। static_assert
के अंदर मैं decltype
का उपयोग कर रहा हूं।
वास्तव में विचित्र बात यह है कि एक नाम के प्रकार decltype
अंदर किसी भी तरह से प्रभावित होता है या नहीं, मेरा आधार स्तरीय टेम्पलेट में एक आभासी नाशक होती है।
#include <type_traits>
#include <utility>
template <typename T>
class Base
{
protected:
template <typename U>
Base(U&& callable)
{
static_assert(
std::is_same<
typename std::remove_reference<decltype(callable())>::type, T
>::value,
"Expression does not evaluate to correct type!");
}
public:
virtual ~Base(void) =default; // Causes error
virtual operator T(void) =0;
};
template <typename T, typename U>
class Derived : public Base<T>
{
public:
Derived(U&& callable) : Base<T>{std::forward<U>(callable)} {}
operator T(void) override final
{
return {};
}
};
void TakesWrappedInt(Base<int>&&) {}
template <typename U>
auto MakeLazyInt(U&& callable)
{
return Derived<
typename std::remove_reference<decltype(callable())>::type, U>{
std::forward<U>(callable)};
}
int main()
{
TakesWrappedInt(MakeLazyInt([&](){return 3;}));
}
ध्यान दें कि यदि नाशक बाहर टिप्पणी की है, तो यह त्रुटि के बिना संकलित:
यहाँ मेरी MCVE है।
आशय callable
प्रकार U
की अभिव्यक्ति है कि, जब ()
ऑपरेटर के साथ कहा जाता है, प्रकार T
के बारे में कुछ रिटर्न होने के लिए है। Base
में आभासी विनाशक के बिना, ऐसा प्रतीत होता है कि इसका मूल्यांकन सही ढंग से किया जाता है; आभासी विनाशक के साथ, ऐसा लगता है कि callabele
का प्रकार Base<T>
है (जहां तक मैं कह सकता हूं, कोई समझ नहीं आता है)।
recursive_lazy.cpp:13:55: error: type 'Base<int>' does not provide a call operator
typename std::remove_reference<decltype(callable())>::type, T
^~~~~~~~
recursive_lazy.cpp:25:7: note: in instantiation of function template specialization
'Base<int>::Base<Base<int> >' requested here
class Derived : public Base<T>
^
1 error generated.
संपादित करें:=delete
कॉपी-निर्माता आईएनजी
recursive_lazy.cpp: In instantiation of ‘Base<T>::Base(U&&) [with U = Base<int>; T = int]’:
recursive_lazy.cpp:25:7: required from ‘auto MakeLazyInt(U&&) [with U = main()::<lambda()>]’
recursive_lazy.cpp:48:47: required from here
recursive_lazy.cpp:13:63: error: no match for call to ‘(Base<int>)()’
typename std::remove_reference<decltype(callable())>::type, T
यहाँ बजना ++ 3.7 के त्रुटि संदेश है:
यहाँ जी ++ 5.1 के त्रुटि संदेश नहीं है भी इस त्रुटि को ट्रिगर करता है।
मैं तुम्हें अजीब आभासी नाशक त्रुटि के बारे में नहीं बता सकता, लेकिन मुझे लगता है कि 'व्युत्पन्न (यू && प्रतिदेय)' एक आर मूल्य लेता है संदर्भ और सार्वभौमिक संदर्भ नहीं। क्या इसका इरादा है? – SirGuy
क्या आप उदाहरण के लिए कुछ आउटपुट जोड़ सकते हैं जो दिखा रहा है कि यह क्या करना है। अंतिम ऑपरेटर टी(); के कारण, TakesWrappedInt को आपके उदाहरण के साथ शून्य नहीं लगता है। –
@GuyGreer नहीं, इसका इरादा नहीं है। ऐसा इसलिए है क्योंकि टेम्पलेट विशिष्ट होने के बाद, यू अब टेम्पलेट प्रकार नहीं है? –