#include <iostream>
#include <array>
#include <type_traits>
template<typename F>
struct length;
template<typename F , std::size_t N = length<F>::value>
class Algorithm
{
public:
Algorithm( F f )
{}
void execute();
private:
F _f;
};
template<typename F , std::size_t N>
void Algorithm<F,N>::execute()
{
_f();
}
struct Curve
{
Curve() = default;
Curve( const Curve& ) = default;
std::array<double,3> operator()() const;
};
std::array<double,3> Curve::operator()() const
{
return {{ 1.0f , 2.0f , 3.0f }};
}
template<>
struct length<Curve> : public std::integral_constant<std::size_t,3>
{};
template<typename F>
Algorithm<F> make_algorithm( F f )
{
return { f };
}
int main()
{
Algorithm<Curve> alg{ Curve{} }; //C++98/03 style
auto alg2 = make_algorithm( Curve{} ); //C++11 style
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8YXJyYXk+CiNpbmNsdWRlIDx0eXBlX3RyYWl0cz4KCnRlbXBsYXRlPHR5cGVuYW1lIEY+CnN0cnVjdCBsZW5ndGg7Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBGICwgc3RkOjpzaXplX3QgTiA9IGxlbmd0aDxGPjo6dmFsdWU+CmNsYXNzIEFsZ29yaXRobQp7CnB1YmxpYzoKICAgIEFsZ29yaXRobSggRiBmICkKICAgIHt9CgogICAgdm9pZCBleGVjdXRlKCk7Cgpwcml2YXRlOgogICAgRiBfZjsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIEYgLCBzdGQ6OnNpemVfdCBOPgp2b2lkIEFsZ29yaXRobTxGLE4+OjpleGVjdXRlKCkKewogICAgX2YoKTsKfQoKc3RydWN0IEN1cnZlCnsKCUN1cnZlKCkgPSBkZWZhdWx0OwoJQ3VydmUoIGNvbnN0IEN1cnZlJiApID0gZGVmYXVsdDsKCQogICAgc3RkOjphcnJheTxkb3VibGUsMz4gb3BlcmF0b3IoKSgpIGNvbnN0Owp9OwoKc3RkOjphcnJheTxkb3VibGUsMz4gQ3VydmU6Om9wZXJhdG9yKCkoKSBjb25zdAp7CglyZXR1cm4ge3sgMS4wZiAsIDIuMGYgLCAzLjBmIH19Owp9Cgp0ZW1wbGF0ZTw+CnN0cnVjdCBsZW5ndGg8Q3VydmU+IDogcHVibGljIHN0ZDo6aW50ZWdyYWxfY29uc3RhbnQ8c3RkOjpzaXplX3QsMz4Ke307Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBGPgpBbGdvcml0aG08Rj4gbWFrZV9hbGdvcml0aG0oIEYgZiApCnsKCXJldHVybiB7IGYgfTsKfQoKCmludCBtYWluKCkKewkKCUFsZ29yaXRobTxDdXJ2ZT4gYWxneyBDdXJ2ZXt9IH07IC8vQysrOTgvMDMgc3R5bGUKICAgIGF1dG8gYWxnMiA9IG1ha2VfYWxnb3JpdGhtKCBDdXJ2ZXt9ICk7IC8vQysrMTEgc3R5bGUKfQoK