Jon*_*Mee 5 c++ templates template-specialization enable-if template-variables
因此,在这个传奇中还有另一个问题。Guillaume Racicot足够出色,可以为我提供另一个解决方法,因此这是我基于以下问题得出的代码:
struct vec
{
double x;
double y;
double z;
};
namespace details
{
template <typename T>
using subscript_function = double(*)(const T&);
template <typename T>
constexpr double X(const T& param) { return param.x; }
template <typename T>
constexpr double Y(const T& param) { return param.y; }
template <typename T>
constexpr double Z(const T& param) { return param.z; }
}
template <typename T, typename = void>
constexpr details::subscript_function<T> my_temp[] = { &details::X<T>, &details::Y<T> };
template <typename T>
constexpr details::subscript_function<T> my_temp<T, enable_if_t<is_floating_point_v<decltype(details::X(T()))>, T>>[] = { &details::X<T>, &details::Y<T>, &details::Z<T> };
int main() {
vec foo = { 1.0, 2.0, 3.0 };
for(const auto i : my_temp<decltype(foo)>) {
cout << (*i)(foo) << endl;
}
}
Run Code Online (Sandbox Code Playgroud)
这个问题似乎在我的专业化会出现,当我返回一些其他的比void。例如,在上面的代码中,enable_if_t<is_floating_point_v<decltype(details::X(T()))>, T>可以防止特殊化,而只需删除最后一个参数并允许enable_if返回就void可以进行特殊化。
我认为这表明了我对这里实际发生的误解。为什么必须始终使用专用类型才能void使其正常工作?
不确定是否了解您不了解的内容,但...
如果你写
template <typename T, typename = void>
constexpr details::subscript_function<T> my_temp[] = { &details::X<T>, &details::Y<T> };
template <typename T>
constexpr details::subscript_function<T> my_temp<T, enable_if_t<is_floating_point_v<decltype(details::X(T()))>, T>>[] = { &details::X<T>, &details::Y<T>, &details::Z<T> };
Run Code Online (Sandbox Code Playgroud)
您有一个带有两个模板的第一个主模板变量:一个类型和一个带有默认值(void)的类型。
当std::enable_if_tis 时启用第二个模板变量void。
当你写的时候会发生什么
for(const auto i : my_temp<decltype(foo)>)
Run Code Online (Sandbox Code Playgroud)
?
编译器:
1)查找my_temp<decltype(foo)>具有单个模板参数
2)寻找一个匹配的my_temp模板变量
3)仅找到my_temp具有两个模板参数的a ,但是第二个具有默认参数,因此
4)决定my_temp<decltype(foo)>只能my_temp<decltype(foo), void>(或my_temp<vec, void>,如果您愿意)
5)看到主要的my_temp比赛
6)看到my_temp专业化不匹配,因为
enable_if_t<is_floating_point_v<decltype(details::X(T()))>, T>
Run Code Online (Sandbox Code Playgroud)
是T(即vec),因此只能匹配与my_temp<vec, vec>有所不同的内容my_temp<vec, void>。
7)选择唯一可用的模板变量:主变量。
如果您希望通过以下方式启用专业化
enable_if_t<is_floating_point_v<decltype(details::X(T()))>, T>
Run Code Online (Sandbox Code Playgroud)
你应该使用 T
// ..............................V T! not void
template <typename T, typename = T>
constexpr details::subscript_function<T> my_temp[] = { &details::X<T>, &details::Y<T> };
Run Code Online (Sandbox Code Playgroud)
作为主模板变量中第二个模板类型的默认值。
离题建议:更好地std::declval在std::is_floating_point_v测试中使用;我建议
std::enable_if_t<std::is_floating_point_v<decltype(details::X(std::declval<T>()))>>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
164 次 |
| 最近记录: |