2017-04-13 9 views
0

작업의 경우 : 내가 위에 나열된 두 경우 모두를 시도하지 않은 그들은 문제없이 컴파일 더 mutable왜 const 객체 안에 정의 된 뮤텍스를 잠글 수 있습니까?

template<typename T> 
class threadsafe_queue 
{ 
private: 
    std::mutex mut; 
    std::queue<T> data_queue; 

public: 
    threadsafe_queue() 
    {} 

    threadsafe_queue(const threadsafe_queue& other) 
    { 
     std::lock_guard<std::mutex> lk(other.mut); 
     data_queue=other.data_queue; 
    } 
}; 

std::mutex mut;에 대한 참고 사항 : 실패

template<typename T> 
class threadsafe_queue 
{ 
private: 
    mutable std::mutex mut; 
    std::queue<T> data_queue; 

public: 
    threadsafe_queue() 
    {} 

    threadsafe_queue(const threadsafe_queue& other) 
    { 
     std::lock_guard<std::mutex> lk(other.mut); 
     data_queue=other.data_queue; 
    } 
}; 

케이스. 내부적으로 lock_guard가 mutex :: lock 함수를 호출한다고 가정합니다.이 함수 자체는 const 함수가 아닙니다.

질문 왜 복사 생성자에서 const 개체의 뮤텍스를 잠글 수 있습니까? 뮤텍스 mutable 될 자격이 때문에

+1

확실하게 '변경 가능'이 핵심입니까? –

+0

@OliverCharlesworth :'mutable' 키워드가 없어지는 두 번째 버전을보십시오. 질문자는 그 버전이 또한 작동한다고보고합니다. – user2357112

+0

@ user2357112 - 실제로 작동하지 않습니다 : http://ideone.com/2MVs0O –

답변

6

예 컴파일. 즉,이 필드는 포함 된 오브젝트가 변경된 것으로 간주되지 않고 변경, 변형 될 수 있습니다. 따라서 뮤텍스의 상태는 "큐의 일부"가 아닙니다. 컴파일러에서는 const 메서드를 사용하여 mutable 멤버를 수정할 수 있습니다.

두 번째 예제는 실제로 클래스를 인스턴스화하지 않고 해당 메서드를 사용하려고하는 경우에만 컴파일됩니다. 너라면, it fails. 템플릿은 마술입니다 ...

+0

'mutable' 키워드가 없어지는 두 번째 버전을보십시오. 질문자는 그 버전이 또한 작동한다고보고합니다. – user2357112

+0

@ user2357112 : 고맙습니다. 편집을 참조하십시오. – einpoklum

+1

템플릿 기능이 합법적이라면'T' permists가 인스턴스화되지 않기 때문에 두 번째는 잘못된 프로그램입니다. 그러나 어떤 진단도 필요하지 않으므로 컴파일러는 자유롭게 컴파일하고 무시할 수 있습니다. 필자는 컴파일러가 추가 진단을 생성 할 수 있도록 허용하지만 필수는 아니라는 규칙이 존재한다고 생각합니다. 말 그대로 해석되는이 규칙의 실제 영향은 표준이 병약 한 프로그램에 대한 행동 제한을 요구하지 않기 때문에 어리 석다. – Yakk