c++ 中带有 typedef 和模板的常量引用

发布于 2024-09-25 05:03:16 字数 462 浏览 15 评论 0原文

我听说临时对象只能分配给常量引用。

但是这段代码给出了错误

#include <iostream.h>    
template<class t>
t const& check(){
  return t(); //return a temporary object
}    
int main(int argc, char** argv){

const int &resCheck = check<int>(); /* fine */
typedef int& ref;
const ref error = check<int>(); / *error */
return 0;
}

The error that is get is invalid初始化类型'int&'的引用来自“const int”类型的表达式

I heard the temporary objects can only be assigned to constant references.

But this code gives error

#include <iostream.h>    
template<class t>
t const& check(){
  return t(); //return a temporary object
}    
int main(int argc, char** argv){

const int &resCheck = check<int>(); /* fine */
typedef int& ref;
const ref error = check<int>(); / *error */
return 0;
}

The error that is get is invalid initialization of reference of type 'int&' from expression of type 'const int'

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

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

发布评论

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

评论(5

水晶透心 2024-10-02 05:03:17

这:

typedef int& ref;
const ref error;

不做你认为它做的事。请考虑一下:

typedef int* pointer;
typedef const pointer const_pointer;

const_pointer 的类型是 int* const不是 const int *。也就是说,当您说 const T 时,您是在说“创建一个 T 不可变的类型”;因此在前面的示例中,指针(而不是被指针)被设为不可变。

不能将引用设为const易失性。 this:

int& const x;

没有意义,因此在引用中添加 cv 限定符没有任何效果。

因此,error 的类型为 int&。您不能为其分配 const int&


您的代码中还存在其他问题。例如,这肯定是错误的:

template<class t>
t const& check()
{
    return t(); //return a temporary object
}

您在这里所做的是返回对临时对象的引用,该对象在函数返回时结束其生命周期。也就是说,如果使用它,您会得到未定义的行为,因为引用对象处没有对象。这并不比:

template<class t>
t const& check()
{
    T x = T();
    return x; // return a local...bang you're dead
}    

更好的测试是:

template<class T>
T check()
{
    return T();
}

函数的返回值是临时的,因此您仍然可以测试是否确实可以将临时值绑定到常量引用。

This:

typedef int& ref;
const ref error;

Doesn't do what you think it does. Consider instead:

typedef int* pointer;
typedef const pointer const_pointer;

The type of const_pointer is int* const, not const int *. That is, when you say const T you're saying "make a type where T is immutable"; so in the previous example, the pointer (not the pointee) is made immutable.

References cannot be made const or volatile. This:

int& const x;

is meaningless, so adding cv-qualifiers to references has no effect.

Therefore, error has the type int&. You cannot assign a const int& to it.


There are other problems in your code. For example, this is certainly wrong:

template<class t>
t const& check()
{
    return t(); //return a temporary object
}

What you're doing here is returning a reference to a temporary object which ends its lifetime when the function returns. That is, you get undefined behavior if you use it because there is no object at the referand. This is no better than:

template<class t>
t const& check()
{
    T x = T();
    return x; // return a local...bang you're dead
}    

A better test would be:

template<class T>
T check()
{
    return T();
}

The return value of the function is a temporary, so you can still test that you can indeed bind temporaries to constant references.

清浅ˋ旧时光 2024-10-02 05:03:17

您的代码给出错误,因为 const ref error 中的 const 限定符被忽略,因为 8.3.2/1

Cv 限定引用的格式不正确,除非通过使用 typedef (7.1.3) 或模板类型参数 (14.3) 引入 cv 限定符,在这种情况下,cv 限定符被忽略。`

因此 error 的类型为 int& 而不是 const int&

Your code gives error because the const qualifier in const ref error is just ignored because 8.3.2/1 says

Cv-qualified references are ill-formed except when the cv-qualifiers are introduced through the use of a typedef (7.1.3) or of a template type argument(14.3), in which case the cv-qualifiers are ignored.`

So error has type int& not const int& .

惜醉颜 2024-10-02 05:03:17

由于英语语法的运作方式,这对于说英语的人来说是一个非常常见的错误。

我认为非常不幸的是,C++ 语法允许两者:

const int // immutable int
int const // immutable int

具有相同的含义。

它并没有让它变得更容易,真的,并且不可组合,因为:

const int* // mutable pointer to immutable int
int* const // immutable pointer to mutable int

当然没有相同的含义。

不幸的是,这对你来说是最重要的,正如 @GMan 所解释的那样。

如果您希望将来避免出现此类错误,请养成在其右侧限定类型(const易失性)的习惯,那么您就可以将 typedef 视为简单的文本替换。

It's a very common mistake for English speaking people, because of the way the English grammar works.

I consider it extremely unfortunate that the C++ syntax would allow both:

const int // immutable int
int const // immutable int

to have the same meaning.

It doesn't make it easier, really, and isn't composable since:

const int* // mutable pointer to immutable int
int* const // immutable pointer to mutable int

certainly do NOT have the same meaning.

And this, unfortunately for you, what kicks in here, as @GMan explains.

If you wish to avoid this kind of error in the future, take the habit of qualifying your types (const and volatile) on their right, then you'll be able to treat a typedef as simple text replacement.

东走西顾 2024-10-02 05:03:17

为了与右左规则保持一致,我更喜欢使用“cv”预选赛就像这样。

int const x = 2; // x is a const int (by applying Right Left rule)

int const *p = &x;  // p is a pinter to const int

在你的例子中,我会这样写 const ref error = check(); 正如

ref const error = check<int>(); // parsed as error is a const reference to an integer

@Prasoon Saurav 指出的那样,通过 typedef 引入时 cv 限定符会被忽略,因为正如 @GMan 也说的那样,简历合格的参考文献格式不正确。

因此,该声明实际上如下,这当然是一个错误。

   int &error = check<int>(); 

请查看了解更多信息。

To maintain consistency with the Right Left Rule, I prefer to use 'cv' qualifiers like so.

int const x = 2; // x is a const int (by applying Right Left rule)

int const *p = &x;  // p is a pinter to const int

In your example, I would write const ref error = check<int>(); like so

ref const error = check<int>(); // parsed as error is a const reference to an integer

As @Prasoon Saurav pointed out, cv qualifiers are ignored when introduced through typedef because as @GMan also says, that cv qualified references are ill-formed.

Therefore the declaration is effectively as below, which of course is an error.

   int &error = check<int>(); 

Check out this for more information.

拥抱影子 2024-10-02 05:03:17

这是编译的:

typedef const int& ref; 
ref error = check<int>(); 

VC++编译器给出了一些错误的解释:限定符应用于引用类型;被忽略。引用类型必须声明为常量,以后不能应用const。

This is compiled:

typedef const int& ref; 
ref error = check<int>(); 

VC++ compiler gives some explanation of your error: qualifier applied to reference type; ignored. Reference type must be declared as constant, const cannot be applied later.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文