我们可以创建一个 IF 语句来确定变量是否已在 C/C 中声明为指针吗?

发布于 2024-11-28 09:51:27 字数 427 浏览 1 评论 0原文

假设变量 pa 始终声明为以下两种方式之一:

双 * pa

双屏

我们可以创建一个执行以下操作的 IF 语句吗

IF(pa是指针) { 帕[0] = 1 }

其他 { pa = 1}

编辑:

请参阅 如何在C++/C中查找指针数组是否已被填充作为后续问题

Suppose a variable pa is always declared as one of two ways:

double * pa

OR

double pa

Can we create an IF statement that does the following

IF (pa is a pointer)
{ pa[0] = 1
}

ELSE
{ pa = 1}

EDIT:

Please see How to find out if a pointer array has been filled in C++/C for the follow up question

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

铁轨上的流浪者 2024-12-05 09:51:27

C++0x std::is_pointer 工作原理的基础知识:

template <typename T>
struct is_pointer_helper {
    static const bool value = false;
};

template <template T>
struct is_pointer_helper<T*> {
    static const bool value = true;
};

对于此示例,我们不想使用该类型,因此我们需要一些模板参数推导:

template <typename T>
bool is_pointer(const T &) {
    return is_pointer_helper<T>::value;
}

我们就完成了:

if (is_pointer(pa)) {
    pa[0] = 1;
} else {
    pa = 1;
}

但是,请注意,除非 pa[0] = 1pa = 1 都是有效表达式(并且对于 double< /code> 也不是 double*它们都有效吗?如果您设置为 0,那么两者都对 double* 有效,但对于 double 仍然只有第二个有效)。因此,您可能想要的不是显式的“if”测试,而是重载函数:

template <typename T>
void set_thingy(T &t) {
    t = 1;
}

template <typename T>
void set_thingy(T *pt) {
    set_thingy(*pt);
}

set_thingy(pa);

或者,因为 pa 始终是 doubledouble* ,没有必要关注一个是指针而另一个不是的事实,它们只是我们需要区别对待的两种不同类型。所以不需要模板:

void set_thingy(double &d) { d = 1; }
void set_thingy(double *p) { *p = 1; }

set_thingy(pa);

The basics of how C++0x std::is_pointer might work:

template <typename T>
struct is_pointer_helper {
    static const bool value = false;
};

template <template T>
struct is_pointer_helper<T*> {
    static const bool value = true;
};

For this example we don't want to have to use the type, so we need some template argument deduction:

template <typename T>
bool is_pointer(const T &) {
    return is_pointer_helper<T>::value;
}

And we're done:

if (is_pointer(pa)) {
    pa[0] = 1;
} else {
    pa = 1;
}

BUT, note that this code still won't compile unless pa[0] = 1 and pa = 1 are both valid expressions (and for neither double nor double* are they both valid - if you were setting to 0 then both would be valid for double*, but still only the second for double). So probably what you want is not an explicit "if" test, but an overloaded function:

template <typename T>
void set_thingy(T &t) {
    t = 1;
}

template <typename T>
void set_thingy(T *pt) {
    set_thingy(*pt);
}

set_thingy(pa);

Or, since pa is always double or double*, there's no need to focus on the fact that one is a pointer and the other is not, they're just two different types that we need to treat differently. So no need for templates:

void set_thingy(double &d) { d = 1; }
void set_thingy(double *p) { *p = 1; }

set_thingy(pa);
苯莒 2024-12-05 09:51:27

不直接,不。假设有一种方法可以做到这一点,例如

if (__IS_POINTER(pa) {
    pa[0] = 1;
}
else {
    a = 1;
}

如果 pa 不是指针会发生什么?您的程序中仍然有 pa[0] = 1; 语句,并且它是非法的,因此编译器将拒绝您的程序。

原则上您也许能够进行编译时测试:

#if __pa_IS_A_POINTER
pa[0] = 1;
#else
a = 1
#endif

但是 C++ 预处理器的功能非常有限;它无法测试变量或表达式的类型。

如果你有这个能力,你会用它做什么?告诉我们您的实际目标是什么。

Not directly, no. Suppose there were a way to do this, something like

if (__IS_POINTER(pa) {
    pa[0] = 1;
}
else {
    a = 1;
}

What happens if pa isn't a pointer? You still have that pa[0] = 1; statement in your program, and it's illegal, so the compiler is going to reject your program.

You might in principle be able to do a compile-time test:

#if __pa_IS_A_POINTER
pa[0] = 1;
#else
a = 1
#endif

but the power of the C++ preprocessor is very limited; it has no way to test the type of a variable or expression.

If you had this capability, what would you do with it? Tell us what your actual goal is.

记忆消瘦 2024-12-05 09:51:27

在 C++0x 中,您可以使用类型特征和 decltype

#include <type_traits>

if (std::is_pointer<decltype(x)>::value)
{
  /* ... */
}

在 C++98/03 中,您没有 decltype,但现在您必须解释你怎么可能在不知道变量类型的情况下拥有它。如果你确实有它的类型,你可以使用相同的类型特征:

#include <tr1/type_traits>
template <typename T> void bogus(T x) // T could be a pointer or not
{
  if (std::tr1::is_pointer<T>::value) { /*...*/ }
}

如果你没有或不想使用 TR1,你也可以定义自己的特征类:

template <typename> struct is_pointer { static const bool value = false; };
template <typename T> struct is_pointer<T*> { static const bool value = true; };

In C++0x you can, using type traits and decltype:

#include <type_traits>

if (std::is_pointer<decltype(x)>::value)
{
  /* ... */
}

In C++98/03 you don't have decltype, but now you'd have to explain how you could possibly have a variable without knowing its type. If you do have its type, you can use the same type trait:

#include <tr1/type_traits>
template <typename T> void bogus(T x) // T could be a pointer or not
{
  if (std::tr1::is_pointer<T>::value) { /*...*/ }
}

You can also just define your own trait class if you don't have or want to use TR1:

template <typename> struct is_pointer { static const bool value = false; };
template <typename T> struct is_pointer<T*> { static const bool value = true; };
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文