所以我有以下的情況下,從長遠例如道歉,但應正確編譯:在編譯時是否可以檢測到以下分配?
#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
與必要的字段來構建(在編譯時所有指定...)
恐怕答案是,這是不可能的(由於類型擦除),但我希望的方式來實現這一功能的一些想法......
你要知道,如果你可以存儲在MATC ......不,先生運行時值編譯時檢測。 – 2013-03-01 11:59:33
您只能在運行時檢查它,但你並不需要'typeid'爲,只是'dynamic_cast' – 2013-03-01 12:12:33
更換'static_cast' @ R.MartinhoFernandes,我不感興趣,在運行時間值,我只想檢查類型。上面的例子稍微有些複雜(通過'mpl :: vector'來生成元組的步驟在那裏,因爲我有一個過濾器函數來移除我不想要的類型)。結果,'set()'只能接受已過濾的*類型* ... – Nim 2013-03-01 12:21:49