Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;:用户定义类型的强制转换_C++_Visual Studio 2008_Casting_Compiler Errors_Compiler Warnings - Fatal编程技术网

C++ C++;:用户定义类型的强制转换

C++ C++;:用户定义类型的强制转换,c++,visual-studio-2008,casting,compiler-errors,compiler-warnings,C++,Visual Studio 2008,Casting,Compiler Errors,Compiler Warnings,如何获得与内置类型相同的用户定义类型的转换操作,例如: float a = 5.4; std::string s = a;//error, no conversion avaible int x = a;//warning, possible data loss int y = (int)a;//fine int z = static_cast<int>a;//fine float b = c;//warning, possible data loss float a=5.4; s

如何获得与内置类型相同的用户定义类型的转换操作,例如:

float a = 5.4;
std::string s = a;//error, no conversion avaible
int x = a;//warning, possible data loss
int y = (int)a;//fine
int z = static_cast<int>a;//fine
float b = c;//warning, possible data loss
float a=5.4;
std::字符串s=a//错误,没有可用的转换
int x=a//警告,可能会丢失数据
int y=(int)a//好的
int z=静态_卡斯塔//好的
浮动b=c//警告,可能会丢失数据
现在假设我有自己的Int和Float类,那么如何获得相同的错误和警告呢

class Int
{
public:
    int value;
    Int(int v);
    ...
};
class Float
{
public:
    float value;
    Float(float v);
    ...
};
Int c = 10;
Float a = 5.5;
std::string s = a;
Int x = a;
Int y = (Int)a;
Int z = static_cast<Int>a;
Float b = c;
class Int
{
公众:
int值;
Int(Int-v);
...
};
班级浮动
{
公众:
浮动值;
浮动(浮动v);
...
};
Int c=10;
浮点数a=5.5;
std::字符串s=a;
Int x=a;
Int y=(Int)a;
Int z=静态_卡斯塔;
浮动b=c;
<>我知道创建超载的CAST运算符,并使用构造函数,但是我不知道如何为隐式和显式转换正确地工作(如考虑)。如果我没有在这些方法中添加显式强制转换,那么在编译时会收到警告,但在调用时不会。如果我添加了显式强制转换,那么在类代码中不会出现错误,但在使用它们时也不会收到警告

我猜有某种方法可以将cast操作符标记为显式,这样,如果它尝试隐式转换,而不是显式(C样式或静态_cast)转换,就会生成警告

编辑: 好的,我想我可以在这样的情况下得到它,所有类型都是完全已知的,但是当一个或两个类型都是模板,并且两个类型都没有映射到内置类型时,情况又如何呢

template<typename T> class Vector2
{
public:
    T x, y;
    Vector2():x(0),y(0){}
    Vector2(T x, T y):x(x),y(y){}

    //Works as expected, warning if adding T and T2 is unsafe, or error if
    //incompatible*/
    template<typename T2>Vector2<T>& operator += (const Vector2<T2> &v);
    //Also works as desired
    Vector2<T>& operator *= (T s);

    //allows the conversion, but always generates warnings if 
    //T and T2 would, even if this constructor is used by an explicit
    //case. How can I suppress the warnings for the explicit cast, but
    //not for implicit casts?
    template<typename T2>Vector2(const Vector2<T2> &v);//uses implicit conversion form T2 to T
};
模板类向量2
{
公众:
tx,y;
向量2():x(0),y(0){}
向量2(tx,ty):x(x),y(y){
//按预期工作,如果添加T和T2不安全,则发出警告;如果
//不相容*/
templateVector2和运算符+=(常量Vector2和v);
//也可以根据需要工作
向量2和运算符*=(ts);
//允许转换,但在以下情况下始终生成警告:
//T和T2,即使该构造函数由显式
//如何抑制显式强制转换的警告,但是
//不适用于隐式强制转换?
templateVector2(const Vector2&v);//使用从T2到T的隐式转换形式
};
从say Vector2到Vector2的隐式强制转换按预期工作,但从say Vector2到Vector2的强制转换始终会导致(2,一个用于x,一个用于y)警告,即使使用了显式C样式或静态_强制转换。我想保留隐式强制转换的警告,但不保留显式强制转换的警告


我知道我可以破解这个问题,创建一个特殊的T vector_cast(T2)类型方法,在内部为每个元素使用显式转换,但我宁愿使用C样式和静态转换,我认为没有任何方法可以为您的转换创建您自己的编译器警告。

有些您想要的东西是不可能的,因为它依赖于编译器对所涉及类型的特殊知识,而你不能教编译器这些东西

您显示的项目应执行以下操作:

Float a = 5.5;
应该毫无怨言地工作

std::string s = a;
Int z = static_cast<int>a;
应该给出一些编译器错误,不一定与使用POD浮点相同,但仍然会拒绝,因为您的浮点没有const char*运算符。(如果是,请将其删除以导致此错误。)

除非Float有一个“operator int()”,否则您仍然应该在这里得到关于可能的数据丢失的警告。如果是,请将其删除,这样编译器将被迫使用“运算符float()”,从而导致警告

Int y = (int)a;
应该毫无怨言地工作

std::string s = a;
Int z = static_cast<int>a;

你没有显示“c”是什么,所以我不能说这会有什么作用。

我也不认为有办法。我所能达到的最好效果是,您想要生成警告的行根本不会编译

class Int
{
public:
    int value;
    Int(int v);
};

class Float
{
public:
    float value;
    Float(float v);
    operator int() { return static_cast<int>(value); }
};

int main()
{
    Float a = 5.5;
    //Int x = a; //no warning, simply doesn't compile
    Int y = (int)a;
    Int z = static_cast<int>(a);
}
另一件事可能是引入一些模板元编程,为安全转换启用转换构造函数

在我看来,boost不包含这样一个
类型的特性,因此我推出了自己的

它有点简化:目标必须至少和源一样大,若源是浮点,则目标不能是整数。但是,它忽略了有符号性问题,以及浮点类型是否可以表示整数类型的完整范围的问题(例如,float不能精确存储所有32位整数,但double可以)

#包括
#包括
模板
结构是\u安全的\u转换:
积分常数<
布尔,
(S)
{
};
模板类向量2
{
公众:
tx,y;
向量2():x(0),y(0){}
向量2(tx,ty):x(x),y(y){
模板
Vector2(const Vector2&other,typename boost::enable_if::type*=0):
x(其他.x),y(其他.y){}
};
模板
矢量2矢量投影(常数矢量2&s)
{
返回向量2(静态_-cast(s.x)、静态_-cast(s.y));
}
int main()
{
矢量2vd,vd2;
向量2 vi,vi2;
向量2 vf,vf2;
vd=vd2;
vd=vi;
vd=vf;
//vi=vd;//错误
vi=矢量投影(vd);
vi=vi2;
//vi=vf;//错误
vi=向量_转换(vf);//显式
//vf=vd;//错误
vf=矢量投影(vd);
//以下编译,但产生警告(float不能表示所有整数)
//TODO:增强是安全的转换!
vf=vi;
vf=vf2;
}
static\u cast通常是安全的,它会给你带来你所期望的结果——要么那样,要么编译失败。reinterpret\u cast是危险的:它会编译,它会运行,你会得到一些毫无意义的东西。
template <class T, class S>
Vector2<T> vector_cast(const Vector2<S>& s)
{
    return Vector2<T>(static_cast<T>(s.x), static_cast<T>(s.y));
}
#include <boost/type_traits.hpp>
#include <boost/utility/enable_if.hpp>

template <class S, class T>
struct is_safe_conversion:
    boost::integral_constant<
        bool,
        (sizeof(S) <= sizeof(T)) && !(boost::is_floating_point<S>::value && boost::is_integral<T>::value)
    >
{
};

template<typename T> class Vector2
{
public:
    T x, y;
    Vector2():x(0),y(0){}
    Vector2(T x, T y):x(x),y(y){}

    template <class U>
    Vector2(const Vector2<U>& other, typename boost::enable_if<is_safe_conversion<U, T> >::type* = 0):
        x(other.x), y(other.y) {}

};

template <class T, class S>
Vector2<T> vector_cast(const Vector2<S>& s)
{
    return Vector2<T>(static_cast<T>(s.x), static_cast<T>(s.y));
}

int main()
{
    Vector2<double> vd, vd2;
    Vector2<int> vi, vi2;
    Vector2<float> vf, vf2;

    vd = vd2;
    vd = vi;
    vd = vf;

    //vi = vd; //error
    vi = vector_cast<int>(vd);
    vi = vi2;
    //vi = vf; //error
    vi = vector_cast<int>(vf); //explicit

    //vf = vd; //error
    vf = vector_cast<float>(vd);

    //following compiles, but produces a warning (float cannot represent all integers) 
    //TODO: enhance is_safe_conversion!
    vf = vi; 
    vf = vf2;
}