2009-06-04 20 views
7

पर जांच करें यदि कुछ वर्ग के कुछ तर्कों के साथ कन्स्ट्रक्टर है तो संकलन समय पर जांच करने का कोई तरीका है? ?संकलित समय वर्ग कन्स्ट्रक्टर हस्ताक्षर

उदाहरण के लिए:

class foo { 
    foo(std::string &s) { 
    } 
}; 

मैं संकलन समय पर जांच करने के लिए एसटीडी के साथ कि निर्माता :: स्ट्रिंग & हमेशा परिभाषित करना चाहते हैं। शायद बढ़ावा ऐसी कार्यक्षमता प्रदान करता है?

+0

आपका मतलब वस्तुओं को बनाने की कोशिश किए बिना है? – Naveen

+1

यदि आप इस कन्स्ट्रक्टर का उपयोग करते समय उपयोग नहीं करते हैं, तो संकलक एक त्रुटि उत्पन्न करेगा। यदि आप इसका उपयोग नहीं करते हैं, तो आप इसे क्यों पेश करना चाहते हैं? –

+0

किसी प्रस्तावित चेक के लिए दिलचस्प टेस्टकेस std :: स्ट्रिंग स्वयं है। – MSalters

उत्तर

3

तुम सच में की जरूरत है, तो आप इस समारोह में जोड़ सकते हैं: अपने निर्माता के बिना

static void _dummy() { std::string s; foo f(s); } 

, संकलन विफल हो जाएगा। नोट: आपका कन्स्ट्रक्टर निजी है। यदि यह उद्देश्य पर है, तो _dummy कक्षा के अंदर होना चाहिए। अन्यथा, आप इसे कक्षा के बाहर रख सकते हैं।

इसके अलावा, यदि आप अपने कोड में बहुत कुछ करते हैं, तो आप टेम्पलेट को भी टेम्पलेट या यहां तक ​​कि इसे मैक्रो बना सकते हैं।

लेकिन सच बताने के लिए, यह अभी भी एक हैक की तरह दिखता है। क्या आपको यकीन है कि आपको इसकी आवश्यकता है?

0

जो आप पूछ रहे हैं वह यूनिट परीक्षण की तरह बहुत कुछ लगता है। मैं cppunit जैसे कुछ डाउनलोड करूंगा और इसे अपने संकलन में एकीकृत कर दूंगा।

किसी भी इकाई परीक्षण आप लिखते हैं का निर्माण किया जाएगा/संकलन समय पर निष्पादित किया। अधिक जानकारी के लिए Unit Testing देखें।

+0

यूनिट परीक्षण वास्तव में संकलित समय पर नहीं हैं, और यह बहुत स्पष्ट रूप से पूछा गया था। पहले से ही 2 समाधान हैं जो साबित करते हैं कि यह काफी संभव है। – MSalters

+0

यूनिट टेस्ट संकलन समय की जांच नहीं हैं, लेकिन जब आप अपना कोड संकलित करते हैं तो उन्हें चलाने के लिए सेटअप किया जा सकता है। यह आपको वैसे भी देता है जो आप शायद किसी भी तरह की तलाश में हैं, जो आपके कोड के बारे में कार्यात्मक अनुबंध और मान्यताओं को सत्यापित करने का एक तरीका है। क्या ऐसा कोई कारण है कि यह संकलन समय पर क्यों होना चाहिए? –

0

आप चेक के इस तरह की जरूरत है, तो आप शायद कुछ अन्य संकलन समय

जाँच मैं एक नज़र डालना (प्रलेखन here है) की अवधारणा पुस्तकालय जाँच बढ़ावा देने के लिए सुझाव है की आवश्यकता होगी। आप कुछ दस्तावेज, कक्षाएं और मैक्रोज़ पा सकते हैं जो आपकी मदद कर सकते हैं।

3

यदि आप यह जांचने की कोशिश कर रहे हैं कि एक स्ट्रिंग से foo रचनात्मक है या नहीं, तो आप boost::is_convertible का उपयोग कर सकते हैं।

उदाहरण के लिए:

BOOST_STATIC_ASSERT((boost::is_convertible<std::string, foo>::value)); 
2

बढ़ावा 1.39 में संकल्पना की जांच का उपयोग करना:

#include <boost/concept_check.hpp> 

class foo_c 
{ 
public: 
    foo_c(std::string& s) 
    {} 
}; 

template<typename T> 
class algo_c 
{ 
BOOST_CONCEPT_ASSERT((boost::Convertible<std::string,T>)); 
public: 
    algo_c() 
    {} 
}; 

निकाला जा रहा है या निम्नलिखित संकलन समय त्रुटि में foo_c परिणाम के निर्माता को बदलने:

error C2440: 'initializing' : cannot convert from 'std::string' to 'foo_c'

संपादित करें: जिसे होमम के साथ स्पष्ट कन्स्ट्रक्टर के साथ काम करने के लिए बनाया जा सकता है एडीई अवधारणा की जांच: एक विशेष समारोह में मौजूद है अगर

template <typename T> 
struct HasTheRightConstructor 
{ 
    BOOST_CONCEPT_USAGE(HasTheRightConstructor) 
    { 
     std::string v; 
     T j(v); 
    } 
}; 
+1

यह विधि स्पष्ट रचनाकारों के लिए काम नहीं करती है। यह केवल 1 गैर-डिफ़ॉल्ट तर्क वाले रचनाकारों के लिए काम करता है। यह काम नहीं करता है, अगर रूपांतरण ऑपरेटर को "std :: string" से टी –

+0

अच्छा बिंदु से परिभाषित किया गया है। संपादित किया गया है कि यह स्पष्ट ctor के साथ काम करता है। वर्ग स्पष्ट ओवरराइड 'टी :: {ctor}' होता है, लेकिन एक अंतरफलक से निकाले जाते हैं नहीं करता है: कैसे एक सटीक प्रोटोटाइप ( –

6

आम तरीका है की जाँच करने के अपने पते लेने के लिए और एक डमी चर निर्दिष्ट करने के लिए है। यह अब तक वर्णित परीक्षणों की तुलना में बहुत अधिक सटीक है, क्योंकि यह सटीक फ़ंक्शन हस्ताक्षर की पुष्टि करता है। और सवाल विशेष रूप से string& हस्ताक्षर में था, इसलिए गैर-कॉन्स और इस प्रकार संभवतः स्ट्रिंग को संशोधित करना था।

हालांकि, इस मामले में आप टेक-द-एड्रेस-एंड-असाइन-इन चाल का उपयोग नहीं कर सकते हैं: रचनाकारों के पास पते नहीं हैं। तो, फिर आप हस्ताक्षर कैसे जांचते हैं? बस: एक डमी वर्ग में इसे मित्र बनाओ।

template<typename T> 
class checkSignature_StringRef { 
    friend T::T(string&); 
}; 

यह भी एक बहुत ही विशेष जांच है: यह भी foo::foo(std::string &s, int dummy = 0) की तरह समान कंस्ट्रक्टर्स मेल नहीं खाएगी।

+0

कि VC8 साथ संकलन नहीं है संकलन करने MSalters से जवाब नहीं कर सकते हैं मैच के लिए क्या करने के लिए पता नहीं है जिसमें फंक्शन घोषणा –

+0

दोष दोष रिपोर्ट को नोट करती है: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#215 –

+0

gcc3 पर क्रैश! gcc4 पर संकलन त्रुटि ... वह विधि अच्छा लग रहा है, लेकिन जब यह निश्चित रूप से एक बहुत चालाक विचार है मैं, पता चला है कि किसी और यह संकलन किया ... –

1

मैं इसी तरह की समस्या के साथ आया था जब तर्कसंगत हैं, जब तर्क संगत होते हैं, और कुछ और करने के लिए नहीं करते हैं।

यहाँ एक सामान्यीकृत लक्षण है MSVC 2013 को काम कर (सी ++ 11 सामान की आवश्यकता है):

namespace detail { 
    template<class type,class...Args> 
    class constructible_from 
    { 
     template<class C> 
     static C arg(); 

     template <typename U> 
     static boost::mpl::true_ constructible_test(U *, decltype(U(arg<Args>()...)) * = 0); 
     static boost::mpl::false_ constructible_test(...); 

    public: 

     typedef decltype(constructible_test(static_cast<type*>(nullptr))) result; 

    }; 
} // namespace detail 

template<class type> 
struct constructible 
{ 
    template<class...Args> 
    struct from : 
     detail::constructible_from<type,Args...>::result {}; 
}; 

यहाँ एक लक्षण के उपयोग का उदाहरण है, मैं छोड़ने एक व्यायाम के रूप enable_if आवेदन: डी:

struct b{}; 
struct c{}; 
struct d : c{}; 

struct a 
{ 
    a() {} 
    a(a &) {} 
    a(b,c) {} 
    a(c) {} 
}; 


static_assert(
    constructible<a>::from<>::value, 
    "a()" 
); 
static_assert(
    constructible<a>::from<a&>::value, 
    "a(a&)" 
); 
static_assert(
    ! constructible<a>::from<const a&>::value, 
    "a(const a&)" 
); 
static_assert(
    constructible<a>::from<b,c>::value, 
    "a(b,c)" 
); 
static_assert(
    ! constructible<a>::from<b>::value, 
    "a(b)" 
); 
static_assert(
    constructible<a>::from<c>::value, 
    "a(c)" 
); 
static_assert(
    constructible<a>::from<d>::value, 
    "a(d)" 
); 
संबंधित मुद्दे