2013-05-09 1 views
4

Clang 3.2는 다음 코드에서 오류를보고하며 문제점이있는 이유를 이해하지 못합니다. 이 오류는 템플릿 함수에서만 발생하며 중괄호가 초기화에 사용 된 경우에만 발생합니다. 다른 두 초기화는 예상대로 작동합니다.일반 초기화시 예기치 않은 변환

bug.cpp:14:9: error: conversion function from 'foo' to 'foo' invokes a deleted function 
    foo b{}; // ERROR 
     ^
bug.cpp:19:5: note: in instantiation of function template specialization 'bar<int>' requested 
     here 
    bar<int>(); 
    ^
bug.cpp:6:5: note: function has been explicitly marked deleted here 
    foo(foo&& rhs) noexcept = delete; 
    ^
1 error generated. 

나는 연타가 변환을 시도 왜 아무 생각이 : 나는 clang++ -Wall -std=c++11 -c으로 코드를 컴파일하는 경우

struct foo { 
    foo() { } 
    ~foo() = default; 
    // deleted 
    foo(const foo& rhs) = delete; 
    foo(foo&& rhs) noexcept = delete; 
    auto operator=(const foo& rhs) -> foo& = delete; 
    auto operator=(foo&& rhs) noexcept -> foo& = delete; 
}; 

template <typename Type> 
void bar() { 
    foo a; // OK 
    foo b{}; // ERROR 
} 

int main() { 
    foo c{}; // OK 
    bar<int>(); 
} 

는 연타 다음과 같은 오류 메시지를 인쇄합니다. 버그 같아. 불행하게도 좀 더 복잡한 코드 기반에서 문제가 발생합니다. 솔루션은 중괄호를 제거하는 것만 큼 쉽지 않습니다.

왜이 경우에 Clang이 변환이 필요한가요? 그리고 어떻게 그것을 일반적으로 작동시킬 수 있습니까?

+0

clang 3.3에서 정상적으로 작동하는 것 같습니다. – Xymostech

+0

정규 반환 대신'-> foo &'를'auto operator ='에서 후행 리턴으로 사용하는 이유는 무엇입니까? – TemplateRex

+1

@rhalbersma : 새 코드에서는 기본적으로 어디에서나 후행 반환 유형을 사용합니다. IMO는 함수 이름이 반환 형식보다 중요하기 때문에 코드의 가독성을 향상시키고 C++ 14에서는 반환 구문을이 구문에서 선택적으로 사용할 수 있습니다. – nosid

답변

5

이것은 분명히 버그입니다. 이 당신이 기본 초기화이 있기 때문에 시도가 이동 생성자를 호출해야한다 아무 이유가 없습니다 :는 상황이 다를 것입니다 참여했다

foo b{}; // Same as "foo b;" in any case 

하면 복사 초기화를, 그러나 그것은 아니다 케이스.

게다가 코드는 GCC 4.7.2에서 정상적으로 컴파일됩니다.

+0

클라 닉의 버그 인 것을 알아두면 좋을 것 같습니다. 이 경우 나는 GCC 4.8에 머무를 것이고 Clang에게 몇 달 안에 또 다른 기회를 줄 것이다. – nosid

+0

@nosid : 좋아, 프로젝트에 행운이 있기를. Btw, Clang 3.2에서 보입니다. 이 작품 –

관련 문제