0
考慮下面的程序:元編程和SFINAE /的std :: enable_if:無限遞歸模板
// Include
#include <iostream>
#include <type_traits>
#include <utility>
#include <tuple>
#include <string>
// Base class
template <class Crtp, class... Types>
struct Base
{
// Constructor calling the transmute function
template <class... OtherTypes>
explicit inline Base(const OtherTypes&... source)
: _data(transmute<std::tuple<Types...>>(std::forward_as_tuple(source...)))
{;}
// Transmute: create a new object
template <class Output>
static constexpr Output transmute()
{return Output();}
// Transmute: forward existing object
template <class Output,
class Input,
class = typename std::enable_if<
std::is_convertible<
typename std::remove_cv<typename std::remove_reference<Input>::type>::type,
typename std::remove_cv<typename std::remove_reference<Output>::type>::type
>::value
>::type>
static constexpr Input transmute(Input&& input)
{return std::forward<Input>(input);}
// Transmute: recursive transmutation
template <class Output,
class... Input,
class = typename std::enable_if<
(sizeof...(Input) <= std::tuple_size<Output>::value)
&& (sizeof...(Input) != std::tuple_size<Output>::value)
>::type>
static constexpr Output transmute(const Input&... input)
{return transmute<Output>(input..., typename std::tuple_element<sizeof...(Input), Output>::type());}
// Transmute: final step
template <class Output,
class... Input,
class = typename std::enable_if<
(sizeof...(Input) == std::tuple_size<Output>::value)
&& (sizeof...(Input) != 0)
>::type>
static constexpr Output transmute(Input&&... input)
{return transmute<Output>(std::forward_as_tuple(std::forward<Input>(input)...));}
// Data member
std::tuple<Types...> _data;
};
// Derived class
struct Derived
: public Base<Derived, std::string, bool>
{
// Universal reference constructor
template <class... Misc>
explicit inline Derived(Misc&&... misc)
: Base<Derived, std::string, bool>(std::forward<Misc>(misc)...)
{;}
};
// Main
int main(int argc, char* argv[])
{
Derived a("hello"); // Boom !!!!
return 0;
}
如果您嘗試編譯,編譯器將「爆炸」,拋出一個相當可觀的錯誤與模板模板模板...
我的問題很簡單:問題在哪裏以及如何解決?
因此類似於構成整個程序和輸入,並說它在運行時崩潰。哪裏出了問題?'做更少的事情。測試每個組件。發現從測試和工作到測試和失敗的變化。包括關於你想要做什麼的豐富文檔。嘗試簡化併產生相同的錯誤,減少死刑。 – Yakk
'(sizeof ...(Input)<= std :: tuple_size
':_data(transmute>(source ...))'並且它編譯(刪除了'std :: forward_as_tuple')。不知道它是否正確。但據我瞭解你的元編程,作爲元組的轉發是不正確的:最後一步期望所有參數* not *被包裝在一個元組中;在你當前的代碼中,''hello''創建的'std :: tuple '不能轉換爲'std :: string',因此轉發永遠不會發生。 –
dyp