正如this previous question中所述,我试图能够为向量分配引用,以便在其上使用stl算法并将更改反映到原始数据中。
#include <vector>
#include <iostream>
#include <algorithm>
using Matrix = std::vector<std::vector<int>>;
/**
* Class implementing std::reference_wrapper that
* cannot be rebound after creation.
*
**/
template <class T>
class single_bind_reference_wrapper {
// pointer to the original element
T *p_;
public: // typedefs
using type = T;
// construct/copy/destroy
single_bind_reference_wrapper(T& ref) noexcept : p_(std::addressof(ref)) {}
single_bind_reference_wrapper(T&&) = delete;
// Enable implicit convertsion from ref<T> to ref<const T>,
// or ref<Derived> to ref<Base>
template <class U, std::enable_if_t<std::is_convertible<U*, T*>{}, int> = 0>
single_bind_reference_wrapper(const single_bind_reference_wrapper<U>& other) noexcept :
p_(&other.get()) { }
// assignment
template <class U>
decltype(auto) operator=(U &&u) const
noexcept(noexcept(std::declval<T>() = std::forward<U>(u))) {
return get() = std::forward<U>(u);
}
// access
operator T& () const noexcept { return *p_; }
T& get() const noexcept { return *p_; }
};
void rotate_mat (Matrix &mat, int r){
auto m = mat.size(); // Number of rows
auto n = mat[0].size(); // Number of columns
auto n_rings = std::min(m,n)/2; // Number of rings
for(auto ring_i=0; ring_i<n_rings; ++ring_i){
// The elements of the ring are stored sequentially
// in v_ring so it can be rotated with std::rotate
std::vector<single_bind_reference_wrapper<int>> v_ring;
std::vector<int*> v_ring_ptr;
// Top side of the ring
for(auto j=ring_i; j<=(n-1)-ring_i; ++j) {
v_ring.push_back(mat[ring_i][j]);
}
// Right side of the ring
for(auto i=ring_i+1; i<=(m-1)-ring_i; ++i) {
v_ring.push_back(mat[i][(n-1)-ring_i]);
}
// Bottom size of the ring
for(auto j=(n-1)-ring_i-1; j>ring_i; --j) {
v_ring.push_back(mat[(m-1)-ring_i][j]);
}
// Left size of the ring
for(auto i=(m-1)-ring_i; i>ring_i; --i) {
v_ring.push_back(mat[i][ring_i]);
}
v_ring[0] = 10; // compilation error!
// This would be my goal:
//std::rotate(v_ring.begin(),v_ring.begin()+r%v_ring.size(),v_ring.end());
}
};
Matrix read_matrix(int m, int n) {
Matrix mat;
mat.reserve(m);
for(auto i=0; i<m; ++i) {
mat.push_back(std::vector<int>{});
mat[i].reserve(n);
for(auto j=0; j<n; ++j) {
int x; std::cin >> x;
mat[i].push_back(x);
}
}
return mat;
};
void print_matrix(Matrix &mat){
for (auto& i : mat){
for (auto& j : i) {
std::cout << j << " ";
}
std::cout << "\n";
}
};
int main() {
int m,n; std::cin >> m >> n;
int r; std::cin >> r;
auto mat = read_matrix(m,n);
rotate_mat(mat,r);
print_matrix(mat);
return 0;
}
目标是能够对std::rotate
v_ring
进行mat
,并查看其对=
原始元素的影响。从来没有,我仍然无法正确实施solution.cc: In function ‘void rotate_mat(Matrix&, int)’:
solution.cc:72:21: warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
v_ring[0] = 10;
^~
solution.cc:34:20: note: candidate 1: decltype(auto) single_bind_reference_wrapper<T>::operator=(U&&) const [with U = int; T = int]
decltype(auto) operator=(U &&u) const
^~~~~~~~
solution.cc:13:7: note: candidate 2: constexpr single_bind_reference_wrapper<int>& single_bind_reference_wrapper<int>::operator=(single_bind_reference_wrapper<int>&&)
class single_bind_reference_wrapper {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
solution.cc:72:21: warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
v_ring[0] = 10;
^~
solution.cc:34:20: note: candidate 1: decltype(auto) single_bind_reference_wrapper<T>::operator=(U&&) const [with U = int; T = int]
decltype(auto) operator=(U &&u) const
^~~~~~~~
solution.cc:13:7: note: candidate 2: constexpr single_bind_reference_wrapper<int>& single_bind_reference_wrapper<int>::operator=(const single_bind_reference_wrapper<int>&)
class single_bind_reference_wrapper {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
solution.cc: In instantiation of ‘decltype(auto) single_bind_reference_wrapper<T>::operator=(U&&) const [with U = int; T = int]’:
solution.cc:72:21: required from here
solution.cc:35:47: error: using xvalue (rvalue reference) as lvalue
noexcept(noexcept(std::declval<T>() = std::forward<U>(u))) {
~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~
solution.cc: In instantiation of ‘decltype(auto) single_bind_reference_wrapper<T>::operator=(U&&) const [with U = int; T = int]’:
solution.cc:72:21: required from here
solution.cc:35:47: error: using xvalue (rvalue reference) as lvalue
运营商。
我得到的编译错误是:
public void Log(Exception ex)
{
// Create an instance of StringBuilder. This class is in System.Text namespace
StringBuilder sbExceptionMessage = new StringBuilder();
sbExceptionMessage.Append("Exception Type" + Environment.NewLine);
// Get the exception type
sbExceptionMessage.Append(exception.GetType().Name);
// Environment.NewLine writes new line character - \n
sbExceptionMessage.Append(Environment.NewLine + Environment.NewLine);
sbExceptionMessage.Append("Message" + Environment.NewLine);
// Get the exception message
sbExceptionMessage.Append(exception.Message + Environment.NewLine + Environment.NewLine);
sbExceptionMessage.Append("Stack Trace" + Environment.NewLine);
// Get the exception stack trace
sbExceptionMessage.Append(exception.StackTrace + Environment.NewLine + Environment.NewLine);
// Retrieve inner exception if any
Exception innerException = exception.InnerException;
// If inner exception exists
while (innerException != null)
{
sbExceptionMessage.Append("Exception Type" + Environment.NewLine);
sbExceptionMessage.Append(innerException.GetType().Name);
sbExceptionMessage.Append(Environment.NewLine + Environment.NewLine);
sbExceptionMessage.Append("Message" + Environment.NewLine);
sbExceptionMessage.Append(innerException.Message + Environment.NewLine + Environment.NewLine);
sbExceptionMessage.Append("Stack Trace" + Environment.NewLine);
sbExceptionMessage.Append(innerException.StackTrace + Environment.NewLine + Environment.NewLine);
// Retrieve inner exception if any
innerException = innerException.InnerException;
}
}