C++11:防止对象被分配给引用

发布于 2024-12-08 20:26:19 字数 2378 浏览 2 评论 0原文

有没有办法创建一个类型 A 这样:

给定:

A f(...);

然后:

两者 auto&& a = f(...);const auto& a = f(...); 给出编译错误?

原因是在这种情况下, A 是一个表达式模板,其中包含对临时变量的引用(作为 f 的参数提供),所以我不希望该对象的生命周期超出了当前表达式。

请注意,我可以通过将 A 的复制构造函数设置为私有并将 f(.. .) A 的朋友(如果需要)。

代码示例 (ideone 链接)

#include <iostream>
#include <array>

template <class T, std::size_t N>
class AddMathVectors;

template <class T, std::size_t N>
class MathVector
{
public:
  MathVector() {}
  MathVector(const MathVector& x) 
  { 
    std::cout << "Copying" << std::endl;
    for (std::size_t i = 0; i != N; ++i)
    {
      data[i] = x.data[i];
    }
  }
  T& operator[](std::size_t i) { return data[i]; }
  const T& operator[](std::size_t i) const { return data[i]; }
private:
  std::array<T, N> data;
};

template <class T, std::size_t N>
class AddMathVectors
{
public:
  AddMathVectors(const MathVector<T,N>& v1, const MathVector<T,N>& v2) : v1(v1), v2(v2) {}
  operator MathVector<T,N>()
  {
    MathVector<T, N> result;
    for (std::size_t i = 0; i != N; ++i)
    {
      result[i] = v1[i];
      result[i] += v2[i];
    }
    return result;
  }
private:
  const MathVector<T,N>& v1;
  const MathVector<T,N>& v2;
};

template <class T, std::size_t N>
AddMathVectors<T,N> operator+(const MathVector<T,N>& v1, const MathVector<T,N>& v2)
{
  return AddMathVectors<T,N>(v1, v2);
}

template <class T, std::size_t N>
MathVector<T, N> ints()
{
  MathVector<T, N> result;
  for (std::size_t i = 0; i != N; ++i)
  {
    result[i] = i;
  }
  return result;
}

template <class T, std::size_t N>
MathVector<T, N> squares()
{
  MathVector<T, N> result;
  for (std::size_t i = 0; i != N; ++i)
  {
    result[i] = i * i;
  }
  return result;
}

int main()
{
  // OK, notice no copies also!
  MathVector<int, 100> x1 = ints<int, 100>() + squares<int, 100>(); 

  // Should be invalid, ref to temp in returned object
  auto&& x2 = ints<int, 100>() + squares<int, 100>(); 
}

Is there any way to create a type A such that:

Given:

A f(...);

Then:

Both auto&& a = f(...); and const auto& a = f(...); give a compile errors?

The reason for this is that in this case, A is an expression template which contains references to temporaries (that are provided as arguments to f), so I don't want the lifetime of this object extended beyond the current expression.

Note I can prevent auto a = f(...); from being an issue just by making As copy constructor private, and making f(...) a friend of A if required.

Example of code (ideone link):

#include <iostream>
#include <array>

template <class T, std::size_t N>
class AddMathVectors;

template <class T, std::size_t N>
class MathVector
{
public:
  MathVector() {}
  MathVector(const MathVector& x) 
  { 
    std::cout << "Copying" << std::endl;
    for (std::size_t i = 0; i != N; ++i)
    {
      data[i] = x.data[i];
    }
  }
  T& operator[](std::size_t i) { return data[i]; }
  const T& operator[](std::size_t i) const { return data[i]; }
private:
  std::array<T, N> data;
};

template <class T, std::size_t N>
class AddMathVectors
{
public:
  AddMathVectors(const MathVector<T,N>& v1, const MathVector<T,N>& v2) : v1(v1), v2(v2) {}
  operator MathVector<T,N>()
  {
    MathVector<T, N> result;
    for (std::size_t i = 0; i != N; ++i)
    {
      result[i] = v1[i];
      result[i] += v2[i];
    }
    return result;
  }
private:
  const MathVector<T,N>& v1;
  const MathVector<T,N>& v2;
};

template <class T, std::size_t N>
AddMathVectors<T,N> operator+(const MathVector<T,N>& v1, const MathVector<T,N>& v2)
{
  return AddMathVectors<T,N>(v1, v2);
}

template <class T, std::size_t N>
MathVector<T, N> ints()
{
  MathVector<T, N> result;
  for (std::size_t i = 0; i != N; ++i)
  {
    result[i] = i;
  }
  return result;
}

template <class T, std::size_t N>
MathVector<T, N> squares()
{
  MathVector<T, N> result;
  for (std::size_t i = 0; i != N; ++i)
  {
    result[i] = i * i;
  }
  return result;
}

int main()
{
  // OK, notice no copies also!
  MathVector<int, 100> x1 = ints<int, 100>() + squares<int, 100>(); 

  // Should be invalid, ref to temp in returned object
  auto&& x2 = ints<int, 100>() + squares<int, 100>(); 
}

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

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

发布评论

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

评论(1

绳情 2024-12-15 20:26:19

给定任何临时对象,在 C++ 中通过将其绑定到 const& 或 && 变量来延长该临时对象的生命周期始终是合法的。最终,如果您正在处理惰性求值等问题,则必须要求用户不要使用 const auto &auto &&。 C++11 中没有任何内容可以让您强行阻止用户这样做。

Given any temporary object, it is always legal in C++ to extend the lifetime of that temporary by binding it to a const& or && variable. Ultimately, if you're dealing with lazy evaluation and the like, you have to ask the user not to use const auto & or auto &&. There's nothing in C++11 that allows you to forcibly prevent the user from doing so.

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