c ++按类型而不是类型声明变量

时间:2014-10-28 16:54:42

标签: c++

有没有办法通过指定类型大小而不是大小本身来定义C ++中的变量?或者有没有办法从函数中返回类型

template<typename T, int L>
class vector {
    public:
    T* __vector;
};

#ifdef USE_FLOAT
typedef vector<float, 3> vec3
#else
typedef vector<double, 3> vec3;
#endif

void myFunc(vec3) {
    float a = vec3.__vector[0];
    // AAHHH but what if vec3 is a vector of doubles?
    // I can get the size of the type by
    int s = sizeof(vec3[0]);
    // So can I declare a variable by just giving the size of the variable?
}

或者,无论如何在类中都有一个可以返回模板类型名的访问器函数吗?

任何建议都会有所帮助。我知道还有其他方法可以解决这个问题,但我特别想知道这两件事中是否有可能。 (我对第二种方法的希望不大。)

我认为第一种方法是通过使用void指针和malloc来实现的......但我宁愿避免使用堆,只要坚持堆栈就可以。

编辑:

为了澄清,我不认为auto会对我的特殊情况有所帮助,但我没有解释原因。这是更完整的代码,并解释了为什么我不认为(肯定是错的)auto无法解决问题。

我有另一个类似的类矩阵。

template<typename T, int L>
class matrix {
    public:
    T* __matrix;
};

#ifdef USE_FLOAT
typedef matrix<float, 4> mat4;
#else
typedef matrix<double, 4> mat4;
#endif

我的myFunc函数看起来更像是这样:

void myFunc(vec3) {
    float a = vec3.__vector[0];
    // AAHHH but what if vec3 is a vector of doubles?
    // I can get the size of the type by
    int s = sizeof(vec3[0]);
    // So can I declare a variable by just giving the size of the variable?

    matrix<sameTypeAsVec3, 4> mat();
}

我只是觉得我可以用auto找出那种类型。但我喜欢错了!

6 个答案:

答案 0 :(得分:6)

在C ++ 11中,您可以使用auto让编译器推导出正确的类型,或decltype

auto a = vec3.__vector[0];

使用std::vector,您有value_type这是值类型,即std::vector<float>::value_typefloat

答案 1 :(得分:4)

C ++解决方案,因为上面的代码是用C ++编写的:

您可以在矢量类中声明一个公共typedef成员,如下所示:

template<typename T, int L>
class vector {
    public:
    T* __vector;

    typedef T value_type; //here
};

然后,您可以使用此成员获取向量中值的类型:

void myFunc(vec3 vec) {
    //declares a to be of the same type as tye elements of vec
    vec::value_type a = vec.__vector[0]; 

这具有完全依赖vec3 API的额外优势,允许您在不破坏功能的情况下更改vec3的实施方式。

答案 2 :(得分:3)

因此。您有一个基于某些宏更改的类型。 所以,让我们给这个类型一个名字!

#ifdef USE_FLOAT
typedef float custom_float;
#else
typedef double custom_float;
#endif

typedef vector<custom_float, 3> vec3;

void myFunc(vec3) {
    custom_float a = vec3.__vector[0];
}

答案 3 :(得分:1)

C ++有auto来做那种“类型推断”:

void myFunc(vec3) {
    float a = vec3.__vector[0];
    // AAHHH but what if vec3 is a vector of doubles?

    // OOHHH - then do this:
    auto b = vec3.__vector[0];
}

您在问题中提到了C,因此只是针对您或任何未来访问者的情况,gcc的语言扩展名为typeof,“返回类型”:

void myFunc(vec3) {
    float a = vec3.__vector[0];
    // AAHHH but what if vec3 is a vector of doubles?

    // Using C? Do that instead:
    typeof(vec3.__vector[0]) b = vec3.__vector[0];
}

编辑:看到您最近的问题版本,auto对您没有帮助。 C ++还有另一个与此密切相关的功能:decltype。它与C中的typeof完全相同,并且完全符合人们的期望。

// Instead of this:
matrix<double, 4> mat;
matrix<float, 4> mat;

// Use this:
matrix<decltype(vec3.__vector[0]), 4> mat;

其名称为decltype,而不是更简单typeof,以提高与C的兼容性。

答案 4 :(得分:1)

  

有没有办法通过指定类型大小而不是大小本身来定义C ++中的变量?

没有。这是不明确的,因为int32_tuint32_tconst uint32_t等都是相同的大小。

  

或者有没有办法从函数中返回一个类型?

不完全正确,但您可以使用decltype获取函数的返回类型,而无需对其进行评估。


无论如何,你真的想要这样的东西:

void myFunc(vec3 vec) {
    matrix<sameUnderlyingTypeAsVec3, 4> mat();
}

现在,如果您的matrixvector类是某些库的一部分,那么将typedef添加到类模板或添加自己的特征类是完全合理的。

或者,您可以使用decltype

或者,您可以将此功能本身设为模板 - 无论如何都会根据您的条件编译选择它:

template <typename T, int N>
void myFunc(vector<T,N> const &vec) {
    matrix<T, N> mat();
}

答案 5 :(得分:0)

更通用的方法(没有额外的typedef或宏,不需要C ++ 11)将使用模板化函数:

template <typename ContainedType>
void myFunc(vector< ContainedType, 3 > vec)
{
    ContainedType a = vec.__vector[0];
}

int main(int argc, char const *argv[])
{
    vec3 vec;
    myFunc(vec);
    return 0;
}

编辑:

你提到想要使用3以外的其他长度,所以更通用的方法就是改变你的vector类:

template<typename T>
class vector
{
    public:
    T* mVector;
    int mLength;
    vector(int len)
    {
        this->mVector = new T[ len ];
        this->mLength = len;
    }
};

然后改变功能:

template <typename ContainedType>
void myFunc(vector< ContainedType > vec)
{
    ContainedType a = vec.mVector[0];
    // If you need to know the length, access vec.mLength;
}