gpt4 book ai didi

C++ 严格的别名规则和指向成员的指针

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:23:01 25 4
gpt4 key购买 nike

以下代码在 G++ 中产生警告:

#include <iostream>
#include <cstdint>

template <typename T, typename P, typename Q>
Q T::*pointer_to(P T::*p, Q P::*q)
{
typedef Q T::* output_ptr;
// warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
size_t tmp = reinterpret_cast<const size_t&>(p) + reinterpret_cast<const size_t&>(q);
return reinterpret_cast<const output_ptr&>(tmp);
}

struct A { int x; };
struct B { A a; };

int main()
{
B b = B();
b.*pointer_to(&B::a, &A::x) = 1;
std::cout << b.a.x << std::endl;
}

无论如何它都能正常工作,但这让我担心。

您怎么看,这些“子成员”指针是否比普通成员指针更容易受到更严格的别名问题的影响?

最佳答案

我建议不要这样做。

您在评论中声明您尝试使用嵌套的 std::bind,但您使用的编译器版本存在问题。我不会诉诸 hack,而是将自己的重复指针滚动到成员类。

#include <iostream>
#include <cstdint>
#include <type_traits>
#include <utility>


template<typename Ptr1, typename... Rest>
class pointer_to_sub;

template<typename ObjType, typename Class>
class pointer_to_sub<ObjType Class::* >
{
typedef ObjType Class::* ptr_type;

public:
typedef ObjType value_type;
typedef Class input_type;
pointer_to_sub(ptr_type input) : ptr(input)
{

}

value_type& operator()(input_type& from) const
{
return from.*ptr;
}

value_type const& operator()(input_type const& from) const
{
return from.*ptr;
}

value_type& operator()(input_type* from) const
{
return from->*ptr;
}

value_type const& operator()(input_type const* from) const
{
return from->*ptr;
}



private:

ptr_type ptr;
};


template<typename ObjType, typename Class, typename... Rest >
class pointer_to_sub<ObjType Class::*, Rest...> : private pointer_to_sub<Rest...>
{
typedef ObjType Class::* ptr_type;
typedef pointer_to_sub<Rest...> base_type;
public:
typedef typename base_type::value_type value_type;
typedef Class input_type;

pointer_to_sub(ptr_type input, Rest... args) : base_type(args...), ptr(input)
{

}

value_type& operator()(input_type& from) const
{
return base_type::operator()(from.*ptr);
}

value_type const& operator()(input_type const& from) const
{
return base_type::operator()(from.*ptr);
}


value_type& operator()(input_type* from) const
{
return base_type::operator()(from->*ptr);
}

value_type const& operator()(input_type const* from) const
{
return base_type::operator()(from->*ptr);
}
private:
ptr_type ptr;
};

template<typename T, typename... Args>
pointer_to_sub<T, Args...> make_pointer_to_sub(T t1, Args... args)
{
return pointer_to_sub<T, Args...>(t1, args...);
}

上面基本上提供了一个make_pointer_to_sub,它接受一个成员对象指针列表。它接受可转换为第一种类型的引用或指针作为其输入,然后依次取消引用每个指针。接受 unique_ptrshared_ptr 可以改进,但那是以后的事。您可以如下所示使用它。

struct A { int x; double y;};
struct B { A a; };

int main()
{
auto ptr = make_pointer_to_sub(&B::a, &A::x);


B b = B();
ptr(b) = 1;
// b.*pointer_to(&B::a, &A::x) = 1;

std::cout << b.a.x << std::endl;
ptr(&b) = 2;
std::cout << b.a.x << std::endl;

}

如果需要,可以将其分配给具有适当参数的 std::function

关于C++ 严格的别名规则和指向成员的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24058465/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com