2016-06-30 5 views
7

मेरे पास कुछ सी ++ 11 कोड है जो विजुअल स्टूडियो 2015 (अपडेट 2) पर संकलित करने में विफल रहता है, लेकिन क्लैंग और जीसीसी दोनों में त्रुटि के बिना संकलित करता है। इसलिए, मुझे विजुअल स्टूडियो में एक कंपाइलर बग पर संदेह है, लेकिन हो सकता है कि मेरा कोड किसी तरह से खराब हो।स्टडी स्टूडियो 2015 पर त्रुटि सी 1001 std :: enable_if

मेरा असली वर्ग BaseUnitdouble मूल्य पर एक टेम्पलेट रैपर वर्ग है, मात्राओं के भौतिक आयामों (एसआई इकाइयों एम, किग्रा, एस, के रूप में व्यक्त) के बारे में देखभाल करते हुए। उदाहरण के लिए, एक समय टेम्पलेट उदाहरण के साथ एक स्पीड का गुणा स्वचालित रूप से एक दूरस्थ उदाहरण देता है। समस्या एक स्केलर के साथ गुणा के वर्तमान कार्यान्वयन के साथ होती है। मैंने कक्षा को उतना ही सरल बना दिया है जितना मैं समस्या को दिखाने के लिए कर सकता था।

#include <type_traits> 

template<int M> 
class BaseUnit 
{ 
public: 
    constexpr explicit BaseUnit(double aValue) : value(aValue) {} 
    template<typename U, typename std::enable_if<std::is_arithmetic<U>::value, int>::type = 0> 
     BaseUnit operator*(U scalar) const { return BaseUnit(value * scalar); } 
    template<typename U, typename std::enable_if<std::is_arithmetic<U>::value, int>::type = 0> 
     friend BaseUnit operator* (U scalar, BaseUnit v) { return BaseUnit(scalar*v.value); } 
protected: 
    double value; 
}; 

int main() 
{ 
    BaseUnit<1> a(100); 
    a = 10 * a; // <-- error C1001 here 
    return 0; 
} 

जब दृश्य स्टूडियो, पर संकलन जो कुछ कमांड लाइन विकल्प, एक आंतरिक त्रुटि C1001 प्रकट होता है:

C:\temp>cl bug.cpp 
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.23918 for x86 
Copyright (C) Microsoft Corporation. All rights reserved. 

bug.cpp 
bug.cpp(19): fatal error C1001: An internal error has occurred in the compiler. 
(compiler file 'msc1.cpp', line 1433) 
To work around this problem, try simplifying or changing the program near the locations listed above. 
Please choose the Technical Support command on the Visual C++ 
Help menu, or open the Technical Support help file for more information 
Internal Compiler Error in C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\cl.exe. You will be prompted to send an error report to Microsoft later. 
INTERNAL COMPILER ERROR in 'C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\cl.exe' 
    Please choose the Technical Support command on the Visual C++ 
    Help menu, or open the Technical Support help file for more information 

कुछ प्रयोगों से, यह होता है कि दोनों operator* परिभाषाओं त्रुटि प्रकट करने के लिए के लिए आवश्यक हैं। यदि या तो उपसर्ग या पोस्टफिक्स संस्करण हटा दिया गया है, तो नमूना कोड ठीक संकलित कर सकता है।

यदि मैं इस व्यवहार को एक बग होने की पुष्टि करता हूं, और संकलक का पहले से ही ज्ञात मुद्दा नहीं है, तो मैं माइक्रोसॉफ्ट पर एक बग रिपोर्ट भर सकता हूं।

+0

डाउनवॉटर पर: क्या आप अपना बिंदु समझा सकते हैं? – prapin

+7

डाउनवॉटर कोई ऐसा व्यक्ति होना चाहिए जो SFINAE से नफरत करता है, जो इसे दोषी ठहरा सकता है। वैसे भी, एक आंतरिक संकलक त्रुटि * हमेशा * एक कंपाइलर बग है। – Praetorian

+1

@Praetorian हां, मुझे लगता है कि भी। लेकिन माइक्रोसॉफ्ट के दस्तावेज यह इंगित करते हैं कि यह उपयोगकर्ता गलती है यदि वह अपने कंपाइलर को दुर्घटनाग्रस्त कर देता है ... – prapin

उत्तर

4

सी ++ मानक के वर्तमान मसौदे के अनुसार:

14.1 Template parameters [temp.param] 
1 The syntax for template-parameters is: 
template-parameter: 
    type-parameter 
    parameter-declaration 
type-parameter: 
    type-parameter-key ...opt identifieropt 
    type-parameter-key identifieropt= type-id 
    template < template-parameter-list > type-parameter-key ...opt identifieropt 
    template < template-parameter-list > type-parameter-key identifieropt= id-expression 
type-parameter-key: 
    class 
    typename 

परिणाम आप सिंटेक्स त्रुटि है (आप के बारे में है कि संकलक ऐसे त्रुटि पता नहीं लगा पाया एमएस रिपोर्ट कर सकते हैं) के रूप में। तो आपके मामले में सही अच्छी तरह से गठित कोड है:

template<int M> 
class BaseUnit 
{ 
public: 
    constexpr explicit BaseUnit(double aValue) : value(aValue) {} 
    template<typename U, typename T = typename std::enable_if<std::is_arithmetic<U>::value, int>::type> 
    BaseUnit<M> operator*(U scalar) const { return BaseUnit<M>(value * scalar); } 
    template<typename U, typename T = typename std::enable_if<std::is_arithmetic<U>::value, int>::type> 
    friend BaseUnit operator* (U scalar, BaseUnit v) { return BaseUnit(scalar*v.value); } 
protected: 
    double value; 
}; 

int main() 
{ 
    BaseUnit<1> a(100); 
    a = 10 * a; // ok 
    a = "19" * a; // error 
    return 0; 
} 
+0

काम करने वाला है या नहीं, आपने यह नहीं बताया कि मूल कोड के साथ क्या गलत था, यदि कुछ भी हो। – Oktalist

+0

वाक्यविन्यास त्रुटि के रूप में आप देख सकते हैं – AnatolyS

+0

आपका कोड VS2015 पर त्रुटि के बिना संकलित करता है, धन्यवाद। लेकिन क्लैंग पर एक संकलन त्रुटि है: 'त्रुटि:' टाइप करें 'टाइप करें' std :: enable_if :: मूल्य, int> :: प्रकार 'क्योंकि' std :: enable_if :: मूल्य, int> 'एक निर्भर दायरा है'। तो वास्तविक अच्छी तरह से गठित वाक्यविन्यास शायद 'टेम्पलेट <टाइपनाम यू, टाइपनाम टी = टाइपनाम std :: enable_if :: मान, int> :: प्रकार> ' – prapin

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