是否有可能在编译时检测到以下赋值

Is it possible to detect the following assignment at compile time?

本文关键字:赋值 检测 有可能 编译 是否      更新时间:2023-10-16

所以我有以下情况,很抱歉这个例子很长,但它应该正确编译:

#include <tuple>
#include <functional>
#include <iostream>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/push_front.hpp>
#include <boost/mpl/vector.hpp>

namespace mpl = boost::mpl;
namespace aux
{
template <typename ...Args>
struct to_vector
{ };
template <typename T, typename ...Args>
struct to_vector<T, Args...>
{ typedef typename mpl::push_front<typename to_vector<Args...>::type, T>::type type; };
template <typename T>
struct to_vector<T>
{ typedef typename mpl::vector<T> type; };
template <>
struct to_vector<>
{ typedef typename mpl::vector<> type; };
template <typename Dest, typename T>
struct tuple_adder
{
  typedef decltype(std::tuple_cat(std::declval<Dest>(), std::make_tuple(std::declval<T>()))) type;
};
}
struct foo
{
  struct storage
  { };
  template <typename T>
  struct placeholder : storage
  {
    placeholder(T&& t) : content(t)
    { }
    T content;
  };
  storage* data;

  template <typename ...Args>
  foo(Args&&... args)
  : data()
  {
    typedef typename mpl::fold<
      typename aux::to_vector<Args...>::type,
      std::tuple<>,
      aux::tuple_adder<mpl::_1, mpl::_2>
    >::type tuple_type;
    // Instantiate the tuple
    data = new placeholder<tuple_type>(std::make_tuple(std::forward<Args>(args)...));
  }
  template <typename ...Args>
  void set(Args&&... args)
  {
    typedef typename mpl::fold<
      typename aux::to_vector<Args...>::type,
      std::tuple<>,
      aux::tuple_adder<mpl::_1, mpl::_2>
    >::type tuple_type;
    auto tp = static_cast<placeholder<tuple_type>*>(data);
    *tp = std::make_tuple(std::forward<Args>(args)...);
  }
};

int main()
{
  foo f(1, 2., std::string("Hello"));
  f.set(4, 3., std::string("Bar"));
  f.set(3., std::string("Bar"), 3.);
}

这个想法很简单,foo使用类型擦除来存储通过构造函数构造的tuple。那么限制应该是set只允许从可变参数列表生成的tuple匹配持有的元组(不幸的是它的类型被擦除)。

现在我可以在运行时使用typeid()检测到这一点,但是,我想知道是否有一种方法可以在编译时进行相同的检测。唯一的限制是foo不能被模板化,variant是出来的,因为我想允许foo在必要时用字段构造(所有在编译时指定…)

我担心答案是这是不可能的(由于类型擦除),但是我希望有一些方法来实现这个功能的想法…

编译时类型系统的意义在于它限制了对类型值允许的操作。如果两个对象类型相同,则它们允许相同的操作。

所以不,编译器没有办法知道你想要允许什么,因为你已经删除了区别