क्या std :: string को constexpr में उपयोग करना संभव है?


175

C ++ 11, Ubuntu 14.04, GCC डिफ़ॉल्ट टूलचिन का उपयोग करना

यह कोड विफल रहता है:

constexpr std::string constString = "constString";

त्रुटि: टाइप 'कास्ट स्ट्रिंग {उर्फ कॉन्स्ट एसटीडी :: basic_string}' कॉन्स्ट्रेक चर का 'कॉन्स्ट्रीमिंग' शाब्दिक नहीं है ... क्योंकि ... 'एसटीडी: basic_string' में एक गैर-तुच्छ विध्वंसक होता है

क्या std::stringए में उपयोग करना संभव है constexpr? (जाहिरा तौर पर नहीं ...) यदि हां, तो कैसे? वहाँ एक चरित्र स्ट्रिंग का उपयोग करने के लिए एक वैकल्पिक तरीका है constexpr?


2
std::stringशाब्दिक प्रकार नहीं है
पियोट स्कॉटनिक

7
@PiotrS - सवाल कहता है कि ...
वेक्टर

4
@ वैक्टर ने मुझसे पूछा कि कॉन्स्टैक्स क्या है या आप std::stringकॉन्स्टैक्स क्यों बनना चाहते हैं ? एसओ पर कई संकलन-समय स्ट्रिंग कार्यान्वयन हैं। यदि आप त्रुटि संदेश को समझते हैं और केवल शाब्दिक प्रकारों को पता लगाया जा सकता है, तो क्या आप गैर-शाब्दिक प्रकार के अवरोध को बना सकते हैं? साथ ही साथ कई कारण हैं कि कोई व्यक्ति एक कॉन्स्ट्रेक्स उदाहरण क्यों चाहता है, इसलिए मैं आपको अपना प्रश्न स्पष्ट करने का सुझाव देता हूं
Piotr Skotnicki

2
हां @PiotrS के रूप में। ने कहा, वहाँ constexprबाहर कार्यान्वयन हैं। std::stringउनमें से एक नहीं है।
दसवाँ

3
@PiotrS - SO - OK, धन्यवाद, समझ पर कई संकलन-समय स्ट्रिंग कार्यान्वयन हैं । यह मेरे लिए एक विकल्प नहीं है, लेकिन यह मेरे सवाल का जवाब देता है: कोई रास्ता नहीं एसटी :: स्ट्रिंग काम करेगा। जैसा कि मैंने टेनफॉर से टिप्पणी की, मैं सोच रहा था कि क्या एसटीडी :: स्ट्रिंग का उपयोग करने का एक तरीका है जो काम करेगा। ऐसी कई तरकीबें हैं जिनसे मैं निश्चित रूप से वाकिफ नहीं हूं।
वेक्टर

जवाबों:


167

नहीं, और आपके कंपाइलर ने पहले ही आपको एक विस्तृत विवरण दिया है।

लेकिन आप ऐसा कर सकते हैं:

constexpr char constString[] = "constString";

रनटाइम के समय, इसका उपयोग std::stringजरूरत पड़ने पर निर्माण के लिए किया जा सकता है ।


78
क्यों नहीं constexpr auto constString = "constString";? जरूरत नहीं है कि बदसूरत सरणी वाक्यविन्यास का उपयोग करने के लिए ;-)
स्टीफन

80
इस प्रश्न के संदर्भ में, यह स्पष्ट है। मेरी बात यह है कि आप किस स्ट्रिंग प्रकार से चुन सकते हैं। जब मैं उपयोग करने के लिए डेटा प्रकार पर जोर देने की कोशिश कर रहा हूं char[]तो उससे अधिक क्रिया / स्पष्ट है auto
दसफोर

7
@tenfour राइट, यह एक अच्छी बात है। मुझे लगता है कि मैं कभी-कभी थोड़ा सा भी इस्तेमाल करने पर ध्यान केंद्रित करता हूं auto;-)
स्टीफ़न

1
@FelixDombek नहीं, लेकिन c ++ 17 के साथ आप constexpr auto s = "c"sv;परिचय के कारण उपयोग कर सकते हैंstring_view
wich

6
क्या यह उस संदर्भ में एक वर्ण सरणी को संकुचित करने के लिए समझ में आता है? यदि आप इसे एक स्ट्रिंग बनाने के लिए उपयोग करते हैं, तो यह वैसे भी कॉपी होने वाला है। स्ट्रिंग के कंस्ट्रक्टर के लिए शाब्दिक पासिंग और इस तरह के एक कॉन्स्ट्रेक्स सरणी को पारित करने के बीच क्या अंतर है?
केजमाग जू

167

के रूप में सी ++ 20 , हाँ।

के रूप में सी ++ 17 , आप उपयोग कर सकते हैं string_view:

constexpr std::string_view sv = "hello, world";

A string_viewएक समान stringवस्तु है जो charवस्तुओं के किसी भी अनुक्रम के लिए एक अपरिवर्तनीय, गैर-मालिकाना संदर्भ के रूप में कार्य करता है ।


6
इस बात से अवगत रहें कि जब भी आप const std::string&किसी नए std :: string को फंक्शन में इस स्थिरांक को पास करते हैं तो इसका निर्माण करना होता है। यह आमतौर पर एक कंटेंट बनाते समय किसी के भी दिमाग में होता है। इसलिए, मैं यह कहना चाहता हूं कि यह एक अच्छा विचार नहीं है। कम से कम आपको सावधान रहना होगा।
रेम्बो रेमन

29
@RamboRamon string_viewस्पष्ट रूप से परिवर्तनीय नहीं है string, इसलिए अकस्मात से निर्माण करने का खतरा बहुत कम stringहै string_view। इसके विपरीत, char const* है परोक्ष के लिए परिवर्तनीय stringहै, इसलिए का उपयोग कर string_viewवास्तव में इस अर्थ में सुरक्षित है।
जोसफ थॉमसन

4
स्पष्टीकरण के लिए धन्यवाद। मैं पूरी तरह से सहमत हूं और वास्तव में भूल गया हूं कि string_viewइसका कोई मतलब नहीं है string। IMO जो समस्या मैं लाया था वह अभी भी मान्य है लेकिन string_viewविशेष रूप से लागू नहीं होती है । वास्तव में, जैसा कि आपने उल्लेख किया है, यह उस संबंध में भी सुरक्षित है।
रेम्बो रेमन

5
यह बहुत अच्छा होगा यदि यह उत्तर string_viewकेवल एक लिंक के बजाय, जो कुछ है, उसके बारे में अधिक कहे ।
एरिक

22

सी ++ 20 constexprतार और वैक्टर जोड़ देगा

निम्नलिखित प्रस्ताव को स्पष्ट रूप से स्वीकार किया गया है : http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0980r0.pdf और यह इस तरह के रूप में निर्माणकर्ताओं को जोड़ता है:

// 20.3.2.2, construct/copy/destroy
constexpr
basic_string() noexcept(noexcept(Allocator())) : basic_string(Allocator()) { }
constexpr
explicit basic_string(const Allocator& a) noexcept;
constexpr
basic_string(const basic_string& str);
constexpr
basic_string(basic_string&& str) noexcept;

सभी / अधिकांश विधियों के कॉन्स्ट्रेक्स संस्करणों के अतिरिक्त।

जीसीसी 9.1.0 के रूप में कोई समर्थन नहीं है, निम्नलिखित संकलन करने में विफल रहता है:

#include <string>

int main() {
    constexpr std::string s("abc");
}

साथ में:

g++-9 -std=c++2a main.cpp

त्रुटि के साथ:

error: the type const string {aka const std::__cxx11::basic_string<char>’} of constexpr variable s is not literal

std::vectorपर चर्चा की: नक्षत्र std :: वेक्टर नहीं बना सकते

उबंटू में परीक्षण 19.04।


19

चूंकि समस्या गैर-तुच्छ विध्वंसक है इसलिए यदि विध्वंसक को हटा दिया जाता है std::string, तो constexprउस प्रकार के उदाहरण को परिभाषित करना संभव है । ऐशे ही

struct constexpr_str {
    char const* str;
    std::size_t size;

    // can only construct from a char[] literal
    template <std::size_t N>
    constexpr constexpr_str(char const (&s)[N])
        : str(s)
        , size(N - 1) // not count the trailing nul
    {}
};

int main()
{
    constexpr constexpr_str s("constString");

    // its .size is a constexpr
    std::array<int, s.size> a;
    return 0;
}

18
यह मूल रूप से c ++ 17 string_viewहै, सिवाय इसके कि string_viewआपको सबसे अधिक कार्यक्षमता प्रदान करता है जिसे आप जानते हैंstd::string
wich
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.