2016-08-13 6 views
9

मैं फ़ंक्शन के बाहर के विपरीत, फ़ंक्शन में constexpr मान का उपयोग नहीं कर सकता।मैं फ़ंक्शन में constexpr मान का उपयोग क्यों नहीं कर सकता, लेकिन मैं इस मान के दायरे में ऐसा कर सकता हूं?

  • मैं दायरे में auto ar1 = std::array<int, il.size()>(); उपयोग कर सकते हैं जहां il परिभाषित किया गया है।

  • लेकिन मैं constexpr समारोह il_to_array()

में { return std::array<T, il.size()>();} उपयोग कर सकते हैं नहीं मैं समारोह में constexpr मूल्य का उपयोग क्यों नहीं कर सकते हैं, लेकिन मैं यह मान के ब्लॉक दायरे में ही कर सकते हैं?

http://ideone.com/5g0iRE

#include <iostream> 
#include <initializer_list> 
#include <array> 

constexpr size_t size_to_size(size_t v) { return v; } // 1 - OK 

template<typename T> 
constexpr size_t il_to_size(std::initializer_list<T> il) { return il.size(); } // 2 - OK 

// 3 - error 
template<typename T> 
constexpr auto il_to_array(std::initializer_list<T> il) {return std::array<T, il.size()>();} 

template<size_t N> 
void print_constexpr() { std::cout << N << std::endl; } 

int main() { 

    constexpr std::initializer_list<int> il = { 1, 2, 3 }; 
    print_constexpr<il.size()>(); // 0 - OK 

    print_constexpr< size_to_size(il.size()) >(); // 1 - OK 

    print_constexpr< il_to_size(il) >(); // 2 - OK 

    auto ar1 = std::array<int, il.size()>(); // OK - body of function: il_to_array() 

    //auto ar2 = il_to_array(il); // 3 - error 

    return 0; 
} 

उदाहरण के लिए, हम देखते हैं, कि टेम्पलेट constexpr-समारोह असफल हो जायेगी नहीं, भले ही यह हो सकता है या constexpr नहीं हो सकता है - टी की निर्भर करता है, क्योंकि उदाहरण में से एक हो सकता है constexpr: Why does the C++ compiler makes it possible to declare a function as constexpr, which can not be constexpr?

  • और यह निष्कर्ष निकाला जा सकता है कि अगर यह एक टेम्पलेट समारोह है, यह विशेषज्ञता के किसी भी हो सकता है: constexpr और गैर constexpr

  • और SFINAE के आधार पर - अगर हम केवल constexpr -arguments का उपयोग तो केवल constexpr -instance को दर्शाता है, और यह कोई फर्क नहीं पड़ता कि गैर constexpr समारोह instantiated नहीं किया जा सकता है।

उत्तर

8

(constexpr) फ़ंक्शंस के तर्क constexpr नहीं हैं।

constexpr कार्यों को तर्क दिया जा सकता है जो संकलन समय पर ज्ञात नहीं थे।

तो निम्नलिखित v संकलन समय पर जाना जाता है या नहीं

constexpr size_t size_to_size(size_t v) { return v; } 

लेकिन निम्नलिखित समारोह il के रूप में काम नहीं करता है कि क्या है constexpr मान्य है नहीं और गैर प्रकार टेम्पलेट पैरामीटर संकलन समय पर जाना जाने की आवश्यकता है:

template<typename T> 
constexpr auto il_to_array(std::initializer_list<T> il) {return std::array<T, il.size()>();} 

यह सच है भले ही फ़ंक्शन केवल संकलन समय पर ज्ञात तर्कों के साथ बुलाया जाता है।

+2

एर ... मुझे यकीन नहीं है कि कहानी ओपी की समस्याओं के लिए यहां समाप्त होती है ... [क्लैंग] (http://coliru.stacked-crooked.com/a/e5440da7ff6a1316) और [एमएसवीसी] (http://webcompiler.cloudapp.net/) ओपी के कोड को संकलित करने में विफल रहता है (केवल जीसीसी करता है)। उन्होंने इसे अस्वीकार कर दिया क्योंकि वे 'std :: startizer_list ' 'constexpr' के निर्माण पर विचार नहीं करते हैं .. जो मेरा मानना ​​है: क्योंकि मानक इसके सदस्यों के कार्यों को छोड़कर 'constexpr' होने के बारे में स्पष्ट नहीं है। एक और सहायक तर्क, क्या होगा यदि 'टी'' std :: startizer_list 'में' constexpr' के रूप में प्रारंभिक नहीं है? – WhiZTiM

+0

@WhiZTiM: [क्यों-नहीं-stdinitializer-list-definition-as-a-literal-type] देखें (http://stackoverflow.com/questions/27496004/why-isnt-stdinitializer-list-defined-as- एक त्रुटि का प्रकार? noredirect = 1 और lq = 1) उस त्रुटि के लिए। – Jarod42

+0

मैं [फोरम चर्चा] तक सभी लिंक के माध्यम से गया (https://groups.google.com/a/isocpp.org/forum/#!topic/std-discussion/aA3BsR4ZuoE/discussion) ..और रिचर्ड स्मिथ की प्रतिक्रिया के अनुसार, क्लैंग और एमएसवीसी 'constexpr std :: startizer_list il = {1,2,3,4}; 'बीमार होने के बारे में सही हैं। – WhiZTiM

संबंधित मुद्दे

 संबंधित मुद्दे