这是另一种选择
template<typename T>
struct Type { typedef T type; };
template<typename T>
inline constexpr Type<T> type{};
template <typename P>
struct Vertex
{
static constexpr auto D3 = []{
if constexpr(std::is_same_v<P,float>)
return type<vec3>;
else if constexpr(std::is_same_v<P,double>)
return type<dvec3>;
else if constexpr(std::is_same_v<P,int>)
return type<ivec3>;
}();
static constexpr auto D2 = []{
if constexpr(std::is_same_v<P,float>)
return type<vec2>;
else if constexpr(std::is_same_v<P,double>)
return type<dvec2>;
else if constexpr(std::is_same_v<P,int>)
return type<ivec2>;
}();
typename decltype(D3)::type position;
typename decltype(D3)::type normal;
typename decltype(D2)::type texcoords;
};
在Type 模板上稍加努力,您就可以对 lambdas 的代码进行相当多的改进(也许您已经看过 boost hana,它也遵循了这个想法)
template<typename T>
struct Type {
typedef T type;
friend constexpr bool operator==(Type, Type) {
return true;
}
};
template<typename T1, typename T2>
constexpr bool operator==(Type<T1>, Type<T2>) {
return false;
}
template<typename T>
inline constexpr Type<T> type{};
现在它不再需要std::is_same_v
template <typename P>
struct Vertex
{
static constexpr auto D3 = [](auto t) {
if constexpr(t == type<float>)
return type<vec3>;
else if constexpr(t == type<double>)
return type<dvec3>;
else if constexpr(t == type<int>)
return type<ivec3>;
}(type<P>);
static constexpr auto D2 = [](auto t) {
if constexpr(t == type<float>)
return type<vec2>;
else if constexpr(t == type<double>)
return type<dvec2>;
else if constexpr(t == type<int>)
return type<ivec2>;
}(type<P>);
typename decltype(D3)::type position;
typename decltype(D3)::type normal;
typename decltype(D2)::type texcoords;
};
丑陋的decltype 写作也可以通过使用auto 来修复
template<auto &t>
using type_of = typename std::remove_reference_t<decltype(t)>::type;
所以你可以写
type_of<D3> position;
type_of<D3> normal;
type_of<D2> texcoords;