テンプレートのインスタンス化の順序がわかりません。「遅すぎる」定義の場合、コンパイラは関数を考慮しないようです。次の手順は、以下のコードの主なアイデアを示しています。
convert<From, To>
関数の作業オーバーロードを見つけることができる場合、フレームワークはフリー関数を提供する必要がありますgenerate
。この関数
to<T>
は のショートカットでconvert<From,To>
あり、有効な場合にのみ機能しconvert<From,To>
ます。ユーザーは、 のオーバーロードを提供し、
generate
および を使用できる必要がto
ありconvert
ます。
対応するコード:
#include <string>
#include <utility>
#include <iostream>
// If I move the code down below at [*] to this location, everything works as
// expected.
// ------------- Framework Code -------------
// Anything that can be generated can also be converted to a string.
template <typename From>
auto convert(From const& from, std::string& to)
-> decltype(
generate(std::declval<std::back_insert_iterator<std::string>&>(), from)
)
{
to.clear();
auto i = std::back_inserter(to);
return generate(i, from);
}
// Similar to convert, except that it directly returns the requested type.
template <typename To, typename From>
auto to(From const& f) -> decltype(convert(f, std::declval<To&>()), To())
{
To t;
if (! convert(f, t))
throw std::invalid_argument("invalid conversion");
return t;
}
// ------------- User Code -------------
// [*] Support arithmetic types.
template <typename Iterator, typename T>
auto generate(Iterator& out, T i)
-> typename std::enable_if<std::is_arithmetic<T>::value, bool>::type
{
// Note: I merely use std::to_string for illustration purposes here.
auto str = std::to_string(i);
out = std::copy(str.begin(), str.end(), out);
return true;
}
int main()
{
uint16_t s = 16;
std::cout << to<std::string>(s) << std::endl;
return 0;
}
generate
次のコードの問題は、関数がandの定義の前にある場合にのみ機能することです。この問題を回避するにはどうすればよいですか?convert
to
ここで私のメンタルモデルが間違っているのかもしれませんが、コンパイラが を参照すると、テンプレートは にto<std::string>(uint16_t)
戻り、必要に応じてインスタンス化を開始すると思いました。任意のガイダンスをいただければ幸いです。