Visual C: пользовательское сообщение об ошибке в классе шаблона - PullRequest
1 голос
/ 25 октября 2019

Код ниже не работает (как и ожидалось). Что меня беспокоит, так это сообщение об ошибке. Там не ясно сказано, в чем проблема. Я бы ожидал что-то вроде “cannot convert from const char* to int”. Вместо этого он говорит "cannot convert from 'initializer list' to 'B<int>'", что становится менее понятно, когда задействованы другие, сложные типы.

Как добавить пользовательское сообщение об ошибке ? Фактический класс намного сложнее.

#include <vector>

template< typename T >
class B
{
  std::vector<T> v;
public:
  B( std::initializer_list<T> il ) : v{ il } {}
};

int main()
{
  B<int> b{ "a","b","c" }; // fails with cannot convert from 'initializer list' to 'B<int>'
}

1 Ответ

3 голосов
/ 25 октября 2019

Если вы хотите иметь только конструктор std::initializer_list<T>, то вы можете просто создать конструктор шаблонов с переменным числом аргументов, а затем в конструкторе есть static_assert, который выдает желаемое сообщение об ошибке. Это работает, потому что если вы предоставите что-то другое, тогда std::initializer_list<T> конструктор будет более подходящим, и assert сработает. Это будет выглядеть как

#include <vector>

template< typename T >
class B
{
    std::vector<T> v;
public:
    B( std::initializer_list<T> il ) : v{ il } {}
    template <typename... Args>
    // the sizeof...(Args) < 0 is needed so the assert will only fire if the constructor is called
    B(Args...) { static_assert(sizeof...(Args) < 0, "This class can only be constructed from a std::initializer_list<T>"); }
};

int main()
{
    //B<int> b1{ "a","b","c" }; // uncomment this line to get static_assert to fire
    B<int> b2{ 1,2,3 };
}
...