2017-03-12 6 views
11

निम्नलिखित कोड डालें:एक कॉन्स्टेक्स मानक मज़ेदार का उचित उपयोग क्या है?

#include <iostream> 
#include <functional> 

template <template<typename> class Op> 
auto applyOp(const uint8_t lhs, const uint8_t rhs) { 
    constexpr Op<uint8_t> op; 

    return op(lhs, rhs); 
} 

int main() { 
    std::cout << +applyOp<std::bit_and>(19, 180) << std::endl; 
} 

जब g++ का उपयोग कर, यह संकलित करता है तथा ठीक चलाता है। हालांकि clang++ एक त्रुटि पैदावार:

test.cpp:5:27: error: default initialization of an object of const type 'const bit_and<uint8_t>' (aka 'const bit_and<unsigned char>') without a user-provided default constructor 
    constexpr Op<uint8_t> op; 
         ^
          {} 
test.cpp:11:19: note: in instantiation of function template specialization 'applyOp<std::bit_and>' requested here 
    std::cout << +applyOp<std::bit_and>(19, 180) << std::endl; 
       ^
1 error generated. 

तो मैं bit_and के लिए स्रोत कोड पर एक दृष्टि डाली:

// Copyright (C) 2001-2016 Free Software Foundation, Inc. 
// 
// This file is part of the GNU ISO C++ Library. This library is free 
// software; you can redistribute it and/or modify it under the 
// terms of the GNU General Public License as published by the 
// Free Software Foundation; either version 3, or (at your option) 
// any later version. 

// This library is distributed in the hope that it will be useful, 
// but WITHOUT ANY WARRANTY; without even the implied warranty of 
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
// GNU General Public License for more details. 

// Under Section 7 of GPL version 3, you are granted additional 
// permissions described in the GCC Runtime Library Exception, version 
// 3.1, as published by the Free Software Foundation. 

// You should have received a copy of the GNU General Public License and 
// a copy of the GCC Runtime Library Exception along with this program; 
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 
// <http://www.gnu.org/licenses/>. 

/* 
    * 
    * Copyright (c) 1994 
    * Hewlett-Packard Company 
    * 
    * Permission to use, copy, modify, distribute and sell this software 
    * and its documentation for any purpose is hereby granted without fee, 
    * provided that the above copyright notice appear in all copies and 
    * that both that copyright notice and this permission notice appear 
    * in supporting documentation. Hewlett-Packard Company makes no 
    * representations about the suitability of this software for any 
    * purpose. It is provided "as is" without express or implied warranty. 
    * 
    * 
    * Copyright (c) 1996-1998 
    * Silicon Graphics Computer Systems, Inc. 
    * 
    * Permission to use, copy, modify, distribute and sell this software 
    * and its documentation for any purpose is hereby granted without fee, 
    * provided that the above copyright notice appear in all copies and 
    * that both that copyright notice and this permission notice appear 
    * in supporting documentation. Silicon Graphics makes no 
    * representations about the suitability of this software for any 
    * purpose. It is provided "as is" without express or implied warranty. 
    */ 

[ ... content omitted ... ] 

template<typename _Arg1, typename _Arg2, typename _Result> 
    struct binary_function 
    { 
     /// @c first_argument_type is the type of the first argument 
     typedef _Arg1  first_argument_type; 

     /// @c second_argument_type is the type of the second argument 
     typedef _Arg2  second_argument_type; 

     /// @c result_type is the return type 
     typedef _Result result_type; 
    }; 

[ ... content omitted ... ] 

#if __cplusplus > 201103L 
    template<typename _Tp = void> 
    struct bit_and; 

    [ ... content omitted ... ] 

#endif 

    [ ... content omitted ... ] 

    // _GLIBCXX_RESOLVE_LIB_DEFECTS 
    // DR 660. Missing Bitwise Operations. 
    template<typename _Tp> 
    struct bit_and : public binary_function<_Tp, _Tp, _Tp> 
    { 
     _GLIBCXX14_CONSTEXPR 
     _Tp 
     operator()(const _Tp& __x, const _Tp& __y) const 
     { return __x & __y; } 
    }; 

    [ ... content omitted ... ] 

मैं क्या बता सकते हैं के लिए, एक डिफ़ॉल्ट निर्माता यहाँ उत्पन्न किया जाना चाहिए। दिलचस्प बात यह है कि त्रुटि संदेश विशेष रूप से "डिफ़ॉल्ट कन्स्ट्रक्टर" के बजाय "उपयोगकर्ता द्वारा प्रदान किए गए डिफ़ॉल्ट कन्स्ट्रक्टर" के लिए पूछता है। ,

- constexpr Op<uint8_t> op; 
+ constexpr Op<uint8_t> op { }; 

मेरा प्रश्न है इन अतिरिक्त ब्रेसिज़ की मांग में clang++ सही है, या g++ नहीं में सही है:

वर्दी आरंभीकरण उपयोग करने के लिए हमलावर लाइन बदलने दोनों compilers के साथ काम करने कोड जाता है?

अतिरिक्त जानकारी

g++ कमांड के साथ संकलन:

g++ test.cpp -Werror -Wall -pedantic -std=c++14 

clang++ कमांड के साथ संकलन:

:

clang++ test.cpp -Werror -Wall -pedantic -std=c++14 

आवेदन आदेश चल रहा है

bit_and स्थान परिभाषा:

/usr/include/c++/6.2.0/bits/stl_function.h 

possible duplicate ध्वज के बारे में, मैं नहीं मानता कि क्यों इस नियम मौजूद है क्योंकि उस सवाल पूछ रहा है इस डुप्लिकेट है, जबकि मेरे सवाल के बारे में जानने के बारे में अधिक था नियम पहले स्थान पर है और कौन सा संकलक इसके प्रवर्तन में सही है। इसके अलावा, कथित डुप्लिकेट के जवाब मेरे प्रश्न का उत्तर नहीं देते हैं।

+1

क्या यह 'constexpr Op सेशन {};' के साथ काम करता है? –

+0

@DanielJour हाँ, धन्यवाद! प्रश्न अपडेट किया गया। – OMGtechy

+0

संभावित डुप्लिकेट [सी ++ को उपयोगकर्ता द्वारा प्रदान किए गए डिफ़ॉल्ट कन्स्ट्रक्टर को डिफ़ॉल्ट रूप से कॉन्स्ट ऑब्जेक्ट बनाने के लिए क्यों आवश्यक है?] (Http://stackoverflow.com/questions/7411515/why-does-c-require-a-user-provided -default-constructor-to-default-construction-a) – Oktalist

उत्तर

9

[dcl.init] में मूल सी ++ 14 शब्दों के लिए आवश्यक है कि:

If a program calls for the default-initialization of an object of a const -qualified type T , T shall be a class type with a user-provided default constructor.

इसलिए, बस एक डिफ़ॉल्ट निर्माता होने के लिए अपर्याप्त है। यह उपयोगकर्ता द्वारा प्रदत्त होने की भी आवश्यकता है। क्लैंग ने इस नियम को लागू किया, जिसके लिए constexpr Op<uint8_t> op{}; की आवश्यकता थी, लेकिन जीसीसी ने इस मामले में डिफ़ॉल्ट-प्रारंभिकरण की अनुमति नहीं दी।

हालांकि, यह शब्द हाल ही में p0490 में संशोधित किया गया था। नए शब्दों, पूर्वव्यापी प्रभाव से सी ++ 14 के लिए आवेदन किया, पढ़ता है:

A class type T is const-default-constructible if default-initialization of T would invoke a user-provided constructor of T (not inherited from a base class) or if
— each direct non-variant non-static data member M of T has a default member initializer or, if M is of class type X (or array thereof), X is const-default-constructible,
— if T is a union with at least one non-static data member, exactly one variant member has a default member initializer,
— if T is a not a union, for each anonymous union member with at least one non-static data member (if any), exactly one non-static data member has a default member initializer, and each potentially constructed base class of T is const-default-constructible.

If a program calls for the default-initialization of an object of a const-qualified type T, T shall be a const-default-constructible class type or array thereof.

Op<uint8_t>स्थिरांक-default-constructible है (तुच्छ कारण यह कोई गैर स्थैतिक डेटा सदस्य हैं के लिए) है, तो आप कर सकते हैं डिफ़ॉल्ट इसे शुरू करें।अब, सी ++ 14 अनुमति देगा:

constexpr Op<uint8_t> op; 

प्रभावी रूप से, हम एक जीसीसी बग से (डिफ़ॉल्ट-प्रारंभ अनुमति) एक बजना बग के पास गया (यह अनुमति न देने)।

+0

तो मैं जो समझता हूं उससे, सी ++ 14 मानक इस नए शब्द को दर्शाने के लिए बदला जाएगा, या भविष्य में रिलीज (जैसे सी ++ 1z)? (मैं दोष प्रक्रिया से परिचित नहीं हूं) – OMGtechy

+1

@OMGtechy C++ 14 इस तरह _changed_ नहीं होगा, लेकिन समिति ने इसे सी ++ 14 में दोष के रूप में वर्णित किया है, तो कार्यान्वयन में नियम लागू होने पर नया नियम लागू हो सकता है सी ++ 14 मोड। – Oktalist

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