2013-03-01 94 views
2

所以我有以下的情況下,從長遠例如道歉,但應正確編譯:在編譯時是否可以檢測到以下分配?

#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與必要的字段來構建(在編譯時所有指定...)

恐怕答案是,這是不可能的(由於類型擦除),但我希望的方式來實現這一功能的一些想法......

+1

你要知道,如果你可以存儲在MATC ......不,先生運行時值編譯時檢測。 – 2013-03-01 11:59:33

+0

您只能在運行時檢查它,但你並不需要'typeid'爲,只是'dynamic_cast' – 2013-03-01 12:12:33

+0

更換'static_cast' @ R.MartinhoFernandes,我不感興趣,在運行時間值,我只想檢查類型。上面的例子稍微有些複雜(通過'mpl :: vector'來生成元組的步驟在那裏,因爲我有一個過濾器函數來移除我不想要的類型)。結果,'set()'只能接受已過濾的*類型* ... – Nim 2013-03-01 12:21:49

回答

3

編譯時類型系統的一點是,它限制了對價值所允許的操作類型。如果兩個對象是相同的類型,那麼他們承認相同的允許操作。

因此,沒有,有沒有辦法讓編譯器知道你想要什麼允許的,因爲你已經刪除的區別。

+0

只要使用類型擦除,我無法找到運行時檢查的方式,所以我想刪除這個問題,但你已經回答了(無論如何是正確的答案),所以我會接受這一點,並離開原來的繁榮。 – Nim 2013-03-01 15:16:33

相關問題