2015-04-25 1 views
1

Я получаю странную ошибку C2535-компилятор при попытке скомпилировать следующий код:C2535 с шаблоном класса в unordered_map (Microsoft Visual Studio 2015 CTP6)

template<int NUMBER> 
class Container { 
public: 
    bool operator==(const Container& other) const { return true; } 
}; 

namespace std { 
    template <int NUMBER> 
    class hash<Container<NUMBER>> { 
    public: 
     size_t operator()(const Container<NUMBER> & state) const { 
      return 0; 
     } 
    }; 
} 

int main(int argc, char* argv[]){ 
    auto* b = new std::unordered_map< Container<1>, int>(); //C2535 
} 

Обратите внимание, что если я использую мой собственный основанный на шаблонах Хашер

template<int NUMBER> 
class Hash { 
public: 
    size_t operator()(const Container<NUMBER> & state) const { 
     return 0; 
    } 
}; 

int main(int argc, char* argv[]){ 
    auto* b = new std::unordered_map< Container<1>, int, Hash<1>>(); 
} 

код компилируется просто отлично. И я помню, что код компилировался без сбоев в Visual Studio 2013 Express.

Вопрос: Это VS 2015 - ошибка или это поведение в некотором роде стандартно-совместимо?

+0

std :: hash не является классом. Это структура. См. Live http://rextester.com/VHHQE6270 – grisha

+0

@ user2451677: Насколько я знаю, struct - это просто класс, при котором доступ по умолчанию является открытым, а не частным. Во всяком случае, с помощью шаблона ** struct ** Hash был отлично скомпилирован! – Mischa

+0

@ user2451677 Хорошая точка. Я думал, что это объявлено «класс хэш». – Columbo

ответ

3

На самом деле, это сделано плохо образованная тонкостью в §14.5.1/4:

В переопределения, частичная специализация, явная специализация или явная конкретизация шаблона класса , класс-ключ согласен в натуральном выражении с декларацией шаблона исходного класса (7.1.6.3).

И, согласно §20.9/2, hash объявлен как

Заголовок <functional> синопсис

// 20.9.12, hash function primary template: 
template <class T> struct hash; 

Поэтому попробуйте

template <int NUMBER> 
struct hash<Container<NUMBER>> { /*…*/ }; 

вместо этого.

+0

Gosh! Это сработало! – Mischa

Смежные вопросы