2014-10-20 5 views
5

मेरे कोड का उपयोग करता std :: सरणी कहो डिफ़ॉल्ट हेडर रैप करने के लिए कैसे में, मैं क्या करना चाहते हैं:C++, साथ वापस आने

फ़ाइल: सरणी

#pragma once 

#ifdef MY_TOOLSET_HAS_STD_ARRAY 
#include <array> //recursive include here? 
#else 
#include <boost/array.hpp> 
namespace std 
{ 
    using boost::array; 
} 
#endif 

इस तरह एसटीडी कि मेरी परियोजना का उपयोग कर सकते कंपाइलर/मंच के बारे में देखभाल किए बिना :: सरणी। एक समस्या (कम से कम) यह है कि जब std :: सरणी उपलब्ध हो, तो शामिल रिकर्सिव होगा, जब मैं वास्तव में चाहता हूं (अर्थात्) "उस हेडर को शामिल करें जिसमें शामिल किया गया होगा यदि इसमें शामिल नहीं था"।

यह कैसे करें इस पर कोई विचार है? मुझे पता है कि एसडीडी में बूस्ट :: सरणी को खींचना भी खराब अभ्यास माना जा सकता है, इसलिए मुझे उस पर विचारों के बारे में भी दिलचस्पी है।

+0

यह अनिर्धारित व्यवहार है। एक दूसरे का प्रयोग करें। –

+0

'सरणी' बूस्ट के मामले के लिए। टी 1 सही चीज करना चाहिए। –

+0

यह वास्तव में तकनीकी रूप से अपरिभाषित व्यवहार है जो 'std' में सामान डालने के लिए, बुरा अभ्यास नहीं है (लेकिन नाक राक्षसों को बुलाए जाने से पहले, इसे ठीक काम करना चाहिए)। मुझे लगता है कि आप अपने हेडर को कुछ अलग नाम देने के लिए सबसे अच्छे हैं (या इसे एक अलग निर्देशिका में डालें, जैसे बूस्ट ने किया है)। – Cameron

उत्तर

7

इस "समस्या" को हल करने का सही तरीका इसे पहले स्थान पर पेश नहीं करना है।

यदि आपके कुछ निर्माण वातावरण सी ++ 11 का समर्थन करते हैं लेकिन अन्य नहीं करते हैं, तो एक सामान्य सबसेट ढूंढें जो आपके सभी निर्माण वातावरण के तहत समर्थित है और इसका उपयोग करें। इस मामले में, वह सामान्य सबसेट बूस्ट प्रतीत होता है। तो आपको boost::array का उपयोग करना चाहिए।

यह भी विचार करें कि यदि आप & std::array का उपयोग करके परीक्षण विकसित करते हैं, तो आपने boost::array का उपयोग करके एक संपूर्ण कोड शाखा छोड़ी है।

मैं आलसी प्रोग्रामिंग के लिए सभी हूं - लेकिन स्मार्ट आलसी प्रोग्रामिंग।आलसी प्रोग्रामिंग का मतलब हैकी या बेकार प्रोग्रामिंग नहीं है, और स्मार्ट आलसी प्रोग्रामिंग को std नामस्थान में जोड़ने के रूप में अपरिभाषित व्यवहार का आह्वान नहीं करती है। कह रहा है, "मैं अपने सभी कोड से गुजरना नहीं चाहता हूं और std::array से boost::array बदलना चाहता हूं" हैक्स और अपरिभाषित व्यवहार को पेश करने का एक अच्छा कारण नहीं है। इन सभी परिवर्तनों को करने के लिए sed को आविष्कार करना उतना आसान हो सकता है, और यह आपको केवल 5 मिनट ले सकता है।

+0

तो मैं असहमत नहीं हूं ... और यह एक विकल्प है। लेकिन यह एक परियोजना है जिसमें बहुत से लोग काम कर रहे हैं, और इस मामले को संभालना अच्छा होगा, जहां सभी को पता नहीं था "ओह, मुझे बूस्ट :: सरणी का उपयोग करना है" ... क्योंकि प्लेटफार्म पर काम करता है पर विकास कर रहे हैं। – user109078

+2

@ user109078 दुर्भाग्यवश यह आपके प्रबंधकों को हल करने में एक समस्या है। –

+0

डेवलपर्स को ऐसे कंपाइलर के साथ विकसित नहीं होना चाहिए जिसका उपयोग प्रोड में नहीं किया जाता है। –

3

यह निश्चित रूप से मैक्रो के लिए उन उपयोग-मामले में से एक है:

// in "my_fixed_array.h" 
#ifdef MY_TOOLEST_HAS_STD_ARRAY 
    #include <array> 
    #define FIX_ARRAY std::array 
#else 
    #include <boost/array.hpp> 
    #define FIX_ARRAY boost::array 
#fi 


// anywhere else 
#include "my_fixed_array.h" 
FIX_ARRAY<char, 4> some_chars; 

इस तरह आप namespace std में सामान रखने जैसा शरारती काम करने के चारों ओर जाने के लिए नहीं है।

+1

मैं दूसरों के लिए बात नहीं कर सकता, लेकिन व्यक्तिगत रूप से मैं (अवैध रूप से) टाइपनामों के लिए मैक्रोज़ का उपयोग करने के बजाय 'std' का विस्तार करूंगा ... – Cameron

+1

@ कैमरॉन मैं मैक्रोज़ का उपयोग करता हूं। कम से कम परिणामस्वरूप कोड कानूनी होगा। –

+3

@ कैमरॉन आपको मैक्रोज़ की आवश्यकता नहीं है। सरणी = std :: सरणी का उपयोग करके 'namepace my {#ifdef MY_TOOLEST_HAS_STD_ARRAY का उपयोग करें; #else सरणी = boost :: सरणी का उपयोग कर; #endif} '। – Praetorian

1

इस पर निर्भर करते हुए कि आपका कंपाइलर कार्यान्वयन कैसे है (और अधिकांश इस संबंध में बहुत अच्छे हैं), आप बस पाथ सर्च ऑर्डर पर भरोसा कर सकते हैं। डिफ़ॉल्ट प्रणाली में पथ सामान्य रूप से उपयोगकर्ता द्वारा निर्दिष्ट "अतिरिक्त" पथ शामिल होने से पहले खोजे जाते हैं।

तो अगर आप एक हैडर array एक गैर मानक में है, जिसका नाम है पथ शामिल है, तो आप मान सकते हैं कि यह केवलशामिल किया जाएगा मानक <array> हैडर वर्तमान नहीं है, प्रणाली के बाद से एक पाया जा होगा पहले अन्यथा। ध्यान दें कि आपको इस तकनीक का उपयोग करके फीचर डिटेक्शन गोप की भी आवश्यकता नहीं है।

(मैं कहा नहीं यह बहुत था -। यह, निर्माण पर्यावरण के दुरुपयोग का एक सा है एक काफी सुरक्षित यद्यपि)

4

आप पूर्व सी ++ 11 उपयोग कर सकते हैं "टेम्पलेट typedef इस के लिए वैकल्पिक हल "है, जो प्रकार के नाम #defining को शामिल नहीं करता है, लेकिन प्रकार थोड़ा भद्दा का उपयोग करने का वाक्य रचना पड़ता है:

#ifdef MY_TOOLSET_HAS_STD_ARRAY 
    #include <array> 
#else 
    #include <boost/array.hpp> 
#endif 

template <typename T, size_t N> 
struct fixed_array 
{ 
    #ifdef MY_TOOLSET_HAS_STD_ARRAY 
     typedef std::array<T, N> type; 
    #else 
     typedef boost::array<T, N> type; 
    #endif 
}; 

फिर प्रकार के आपके उपयोग हो जाता है:

typename fixed_array<char, 4>::type some_chars; 

Howeve आर, boost::array का उपयोग करने के लिए यह काफी आसान होगा। इसका मतलब है कि आपको कम से कम क्रमिक परीक्षण करना होगा और इसलिए कोडबेस पर रखरखाव लागत कम हो जाती है।

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