[英]Boost.Variant, Boost.MPL: How to append types?
我看一下基於boost.The的爐排代碼。有什么不由自主的 ,但想知道我們是否可以使用Boost.Variant 。 我不知道這樣的API是否可能:
void voidFunc()
{
std::cout << "void called" << std::endl;
}
int stringFunc(std::string str)
{
std::cout << str << std::endl;
return 0;
}
int main()
{
some_map_like_type<std::string, boost::variant> funcs;
funcs.insert<void , void >("voidFunc", &voidFunc)); // now our variant vould contain something like boost::function<void, void>
funcs.insert<int , std::string>("stringFunc", &stringFunc)); // and now we added to our variant a new type: boost::function<int , std::string>
funcs.insert<void , void >("voidFunc2", &voidFunc)); // and now our variant should not change because it already contains boost::function<void, void> type
// And here when all the fun part is:
funcs["voidFunc"](); // compiles
funcs["stringFunc"]("hello"); // compiles
funcs["stringFunc"](some_not_std_string_class); // does not compile.
return 0;
}
這意味着最終編譯器將不得不編譯如下內容:
void voidFunc()
{
std::cout << "void called" << std::endl;
}
int stringFunc(std::string str)
{
std::cout << str << std::endl;
return 0;
}
int main()
{
some_map_like_type<std::string, boost::variant< boost::function<void , void>, boost::function<int , std::string> > > funcs;
funcs.insert<void , void >("voidFunc", &voidFunc)); // now our variant vould contain something like boost::function<void, void>
funcs.insert<int , std::string>("stringFunc", &stringFunc)); // and now we added to our variant a new type: boost::function<int , std::string>
funcs.insert<void , void >("voidFunc2", &voidFunc)); // and now our variant should not change because it already contains boost::function<void, void> type
// And here when all the fun part is:
funcs["voidFunc"](); // compiles
funcs["stringFunc"]("hello"); // compiles
funcs["stringFunc"](some_not_std_string_class); // here it would give error and would not compile
return 0;
}
我嘗試了什么(基於此Variant文檔以及本MPL演示和文檔 ):
#include <boost/static_assert.hpp>
#include <boost/mpl/equal.hpp>
#include <boost/mpl/vector_c.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/multiplies.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/variant.hpp>
#include <iostream>
#include <string>
#include <vector>
class sudo_science
{
public:
typedef boost::mpl::vector_c<int> types_vector1;
typedef boost::make_recursive_variant< types_vector1 >::type recursive_variant_t;
std::vector< recursive_variant_t > variant_seq;
template <typename T>
void append(T val)
{
typedef boost::mpl::push_back<types_vector1,T>::type types_vector1;
variant_seq.push_back(val);
return;
}
std::vector< recursive_variant_t > give_me_end_variant()
{
return variant_seq;
}
};
int main()
{
sudo_science a;
a.append<float>(1.0);
a.append<std::string>("Stack and Boost");
//sorry for C++11
auto varint = a.give_me_end_variant();
return 0;
}
但是它無法編譯時出現兩個相同的錯誤:
Error 1 error C2665: 'boost::detail::variant::make_initializer_node::apply<BaseIndexPair,Iterator>::initializer_node::initialize' : none of the 2 overloads could convert all the argument types c:\program files\boost\include\boost\variant\variant.hpp 1330 1
這不可能。 operator[]
是運行時事物,而類型是編譯時事物。 那么編譯器應該編譯以下內容嗎?
char const* str;
if (some_condition())
str = "voidFunc";
else
str = "stringFunc";
// ... some more code
if (some_condition())
funcs[str]();
else
funcs[str](str);
編譯器應該如何知道對some_condition()
的第二次調用是否給出與以前相同的結果? 還是代碼之間是否修改了str
的值?
關於以下內容:
void call(some_map_like_type<std::string, boost::variant> const& funcs)
{
funcs["voidFunc"]();
}
編譯器應該如何知道是否在通話時間funcs
包含的條目映射"voidFunc"
,以不帶參數的函數嗎? 如果一次調用一個帶有值的值,一次調用一個不帶值的值,那會發生什么呢?
根據您實際想要實現的目標,可能會有一種使用模板和constexpr
函數來獲取它的方法。 但是請注意,運行時發生的任何事情都不會影響代碼是否編譯,原因很簡單,即代碼在編譯之前無法運行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.