Подавить предупреждение компилятора для определенного кода шаблона
Я реализовал класс шаблонов для обнаружения конвертируемости двух типов (следуя методу, описанному в книге "Современный дизайн C++" Андрея Александреску раздел 2.7).
Осуществленная мною реализация выглядит следующим образом:
#include <utility>
#include <iostream>
template<typename T, typename U>
class Conversion
{
private:
using Small = char;
using Big = class{ char dummy[2]; };
static Small Test(U);
static Big Test(...);
public:
enum
{
exists = (sizeof(Test(std::declval<T>())) == sizeof(Small)) // Warning related to conversion.
};
};
int main()
{
std::cout << "Conversion int to float :" << Conversion<int, float>::exists << "n";
return 0;
}
При компиляции этого кода на Visual Studio 2013(Visual C++ 2013 ), я получаю следующее предупреждение, связанное с преобразованием из int в float
Предупреждение C4244: 'аргумент': преобразование из 'int' в 'float', возможно потеря данных.
Поскольку это было неявным требованием здесь, есть ли способ подавить это предупреждение?
Я просто хочу подавить его только для этого случая. Если такое преобразование выполняется в других местах, компилятор все равно должен генерировать предупреждение.3 ответа:
Во-первых, если у кого-то есть желание подавить /правильное/ предупреждение, то он, скорее всего, делает что-то неправильно. В этом случае тестер может быть переписан для выполнения преобразования
explicit
. Это также позволит ему обрабатывать определяемые пользователем операторы преобразованияexplicit
(которые не покрываются вашим исходным кодом или::std::is_convertible
):#include <utility> #include <type_traits> #include <iostream> template<typename Anything> class Void { public: using type = void; }; template<typename T, typename U, typename Enabled = void> class Conversion : public ::std::false_type {}; template<typename T, typename U> class Conversion<T, U, typename Void<decltype(static_cast<U>(::std::declval<T>()))>::type> : public ::std::true_type {}; struct foo{ explicit operator int(void) const; }; int main() { ::std::cout << "Conversion short to int :" << Conversion<short, int>::value << "\n"; ::std::cout << "Conversion int to short :" << Conversion<int, short>::value << "\n"; ::std::cout << "Conversion int to float :" << Conversion<int, float>::value << "\n"; ::std::cout << "Conversion float to int :" << Conversion<float, int>::value << "\n"; ::std::cout << "Conversion float to foo :" << Conversion<float, foo>::value << "\n"; ::std::cout << "Conversion foo to float :" << Conversion<foo, float>::value << "\n"; ::std::cout << "Conversion int to foo :" << Conversion<int, foo>::value << "\n"; ::std::cout << "Conversion foo to int :" << Conversion<foo, int>::value << "\n"; return 0; }
Есть также
std::is_convertible
В C++11:#include <utility> #include <iostream> template<typename T, typename U> class Conversion { private: using Small = char; using Big = class{ char dummy[2]; }; static Small Test(U); static Big Test(...); public: enum { exists = (sizeof(Test(std::declval<T>())) == sizeof(Small)) // Warning related to conversion. }; }; int main() { std::cout << "Conversion int to float :" << Conversion<int, float>::exists << "\n"; std::cout << "Conversion int to float :" << Conversion<float, int>::exists << "\n"; std::cout << "Conversion int to float :" << std::is_convertible<int,float>::value << "\n"; std::cout << "Conversion int to float :" << std::is_convertible<float, int>::value << "\n"; return 0; }
У меня здесь нет локального Visual C++, но онлайн-компилятор не генерирует предупреждение для
std::is_convertible
с уровнем предупреждения 4:Warning(s): source_file.cpp(15): warning C4244: 'argument': conversion from 'std::ios_base::iostate' to 'float', possible loss of data source_file.cpp(21): note: see reference to class template instantiation 'Conversion<int,float>' being compiled source_file.cpp(15): warning C4244: 'argument': conversion from 'float' to 'int', possible loss of data source_file.cpp(22): note: see reference to class template instantiation 'Conversion<float,int>' being compiled /LIBPATH:C:\boost_1_60_0\stage\lib Microsoft (R) C/C++ Optimizing Compiler Version 19.00.23506 for x64 Conversion int to float :1 Conversion int to float :1 Conversion int to float :1 Conversion int to float :1