1
我希望能夠使用不在我控制範圍內的變體類打包的參數調用任意函數(我們稱之爲blackbox
)。我寫了一個函數模板unpack<T>
,它從blackbox
中提取需要專門用於目標類型的值。這適用於通過值傳遞的參數。但是,我不知道如何處理傳遞引用:如何將T轉發到以const&T爲參數的函數
#include <string>
#include <functional>
#include <iostream>
#include <utility>
#include <type_traits>
/* Variant container */
struct blackbox
{
int int_value() const { return 42; }
bool bool_value() const { return true; }
std::string string_value() const { return "str"; }
};
/* Unpack function templates */
template<typename T>
T unpack(const blackbox &v)
{
static_assert(sizeof(T) == 0, "This template has to be specialized");
}
template<>
int unpack(const blackbox &v)
{
return v.int_value();
}
template<>
bool unpack(const blackbox &v)
{
return v.bool_value();
}
template<>
std::string unpack(const blackbox &v)
{
return v.string_value();
}
/* Call function with arguments extracted from blackbox */
template<typename T>
void call(std::function<void(T)> f, const blackbox &v)
{
f(unpack<T>(v));
}
/* Sample functions */
void f_int(int i) { std::cout << "f_int(" << i << ")" << std::endl; }
void f_bool(bool b) { std::cout << "f_bool(" << b << ")" << std::endl; }
void f_str(std::string s) { std::cout << "f_str(" << s << ")" << std::endl; }
void f_str_ref(const std::string &s) { std::cout << "f_str_ref(" << s << ")" << std::endl; }
int main()
{
blackbox b;
// direct call
f_str_ref(b.string_value());
// indirect call
call(std::function<void(int)>(f_int), b);
call(std::function<void(bool)>(f_bool), b);
call(std::function<void(std::string)>(f_str), b);
call(std::function<void(const std::string&)>(f_str_ref), b); //doesn't work
return 0;
}
我需要unpack
專業化轉發std::string
情況下受到充分const std::string&
參數的函數。定義
template<>
const std::string& unpack(const blackbox &v)
{
return v.string_value();
}
顯然不起作用,因爲返回了對局部變量的引用。沒有爲const std::string&
專門定義unpack
會導致靜態斷言失敗。
理想情況下,unpack<std::string>
應該用於const std::string&
,但提供單獨的專業化就足夠了。
你試過'f(unpack :: type>(v));'? –
2014-10-29 15:46:16
謝謝,'std :: decay'是我正在尋找的。 –
2014-10-29 16:59:29
@PiotrS。你的評論有資格作爲答案,我很樂意接受它。 – 2014-11-02 09:48:21