抑制特定模板代码的编译器警告

Suppress compiler warning for specific template code

我已经实现了一个模板 class 来检测两种类型的可转换性(按照 Andrei Alexandrescu 的《现代 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

warning C4244: 'argument' : conversion from 'int' to 'float', possible loss of data.

因为这是一个隐含的要求,有没有办法抑制这个警告?

我只是为了这个案子才想压制它。如果在其他地方进行此类转换,编译器仍应生成警告。

根据 documentation.

使用 #pragma warning(suppress, …

C++11中还有std::is_convertible

#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++,but the online compiler does not generate a warning for std::is_convertible with warning level 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

第一件事是,如果有人有压制 /correct/ 警告的冲动,那么他很可能做错了什么。在这种情况下,可以重写测试器以执行 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;
}

online compiler, no error with /W4 on vc++