I have implemented a template class to detect the convertability of two type (following the method described in the book Modern C++ Design by Andrei Alexandrescu Section 2.7).
The implementation I made is as follows:
#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;
}
On compiling this code on Visual Studio 2013(Visual C++ 2013), I get following warning related to conversion from int to float
warning C4244: 'argument' : conversion from 'int' to 'float', possible loss of data.
As it was an implicit requirement here, is there a way to suppress this warning?
I just want to suppress it for this case alone. If such conversion is being done in other places, compiler should still generate the warning.
答案 0 :(得分:1)
Use #pragma warning(suppress, …
, as per the documentation.
答案 1 :(得分:1)
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;
}
:
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
我这里没有本地的Visual C ++,but the online compiler does not generate a warning for std::is_convertible
with warning level 4:
{{1}}
答案 2 :(得分:1)
首先,如果某人有压迫/纠正/警告的冲动,那么他很可能会做错事。在这种情况下,可以重写测试程序以执行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;
}