कुछ खुदाई यह std::initializer_list
का उपयोग कर की तरह लग रहा करने के बाद यह घोषणा में constexpr
की कमी के कारण नहीं जीसीसी 4.7 में संभव है। यह जीसीसी 4.8 के साथ <initializer_list>
के साथ काम constexpr
शामिल करने के लिए अद्यतन किया गया है। दुर्भाग्य से जीसीसी 4.8 का उपयोग इस समय एक विकल्प नहीं है।
किसी भी सरणी के तत्वों को एक्सेस करना संभव है यदि क्षय पॉइंटर संदर्भ द्वारा पारित किया गया हो। यह सत्यापन को वांछित होने की अनुमति देता है लेकिन अभी भी वह समाधान नहीं है जिसके लिए मैं उम्मीद कर रहा हूं। निम्नलिखित कोड सरणी के लिए एक व्यावहारिक समाधान है। यह अभी भी आवश्यक है कि सरणी का आकार सत्यापन समारोह में प्रदान किया जाए लेकिन यह सही करने के लिए पर्याप्त आसान है।
#include <initializer_list>
template<typename T>
constexpr bool Compare(T& data, int size, int needleIndex, int haystackIndex)
{
return
needleIndex == haystackIndex ?
Compare(data, size, needleIndex + 1, haystackIndex)
: needleIndex == size ?
false
: data[needleIndex] == data[haystackIndex] ?
true
: Compare(data, size, needleIndex + 1, haystackIndex);
}
template<typename T>
constexpr bool Compare(T& data, int size, int index)
{
return
index == size ?
false
: Compare(data, size, index + 1) ?
true
: Compare(data, size, 0, index);
}
template<typename T, int ArraySize>
constexpr bool Validate(T(&input)[ArraySize], int size)
{
return !Compare(input, size, 0);
}
int main()
{
constexpr int initData0[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
constexpr int initData1[] = {1, 1, 2, 3, 4, 5, 6, 7, 8, 9};
constexpr int initData2[] = {2, 1, 2, 3, 4, 5, 6, 7, 8, 9};
constexpr int initData3[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 8};
constexpr int initData4[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 7};
constexpr int initData5[] = {0, 1, 0, 3, 4, 5, 6, 7, 8, 9};
constexpr int initData6[] = {0, 1, 2, 3, 4, 5, 6, 9, 8, 9};
static_assert(Validate(initData0, 10), "set 0 failed"); // <-- PASS
static_assert(Validate(initData1, 10), "set 1 failed"); // <-- (and below) FAIL
static_assert(Validate(initData2, 10), "set 2 failed");
static_assert(Validate(initData3, 10), "set 3 failed");
static_assert(Validate(initData4, 10), "set 4 failed");
static_assert(Validate(initData5, 10), "set 5 failed");
static_assert(Validate(initData6, 10), "set 6 failed");
}
।
बिल्ड लॉग:
C:\Source\SwitchCaseString\main.cpp: In function 'int main()':
C:\Source\SwitchCaseString\main.cpp:198:2: error: static assertion failed: set 1 failed
C:\Source\SwitchCaseString\main.cpp:199:2: error: static assertion failed: set 2 failed
C:\Source\SwitchCaseString\main.cpp:200:2: error: static assertion failed: set 3 failed
C:\Source\SwitchCaseString\main.cpp:201:2: error: static assertion failed: set 4 failed
C:\Source\SwitchCaseString\main.cpp:202:2: error: static assertion failed: set 5 failed
C:\Source\SwitchCaseString\main.cpp:203:2: error: static assertion failed: set 6 failed
के लिए वर्तमान प्रस्ताव के अनुसार [सी ++ 14] (http://isocpp.org/files/papers/N3690.pdf), 'शुरू()' और ' 'std :: startizer_list' का अंत() 'भविष्य में' constexpr' होगा (18.9/1 देखें)। इससे एक बाधा दूर हो जाती है, लेकिन मुझे यकीन नहीं है कि संकलन समय पर पुनरावर्तक मानों को संदर्भित करना संभव होगा या नहीं। – jogojapan
@jogojapan: 'std :: startizer_list' "iterators" केवल 'T *' - गारंटीकृत हैं। –
Xeo
@Xeo हां, और मैंने माना कि इस तरह के सूचक को निरंतर अभिव्यक्ति में अनुमति नहीं दी जाएगी। – jogojapan