假设我有一个包含值的LimitedValue类,并在int类型'min'和'max'上进行参数化.您可以将它用作容纳值的容器,该值只能在一定范围内.你可以使用它:
LimitedValue< float, 0, 360 > someAngle( 45.0 );
someTrigFunction( someAngle );
Run Code Online (Sandbox Code Playgroud)
这样'someTrigFunction'知道它可以保证提供有效的输入(如果参数无效,构造函数会抛出异常).
但是,复制构造和分配仅限于完全相同的类型.我希望能够做到:
LimitedValue< float, 0, 90 > smallAngle( 45.0 );
LimitedValue< float, 0, 360 > anyAngle( smallAngle );
Run Code Online (Sandbox Code Playgroud)
并在编译时检查该操作,因此下一个示例给出了一个错误:
LimitedValue< float, -90, 0 > negativeAngle( -45.0 );
LimitedValue< float, 0, 360 > postiveAngle( negativeAngle ); // ERROR!
Run Code Online (Sandbox Code Playgroud)
这可能吗?是否有一些实际的方法可以做到这一点,或者有哪些例子可以解决这个问题?
我读了很多问题和答案,但这个问题引起了我的注意; 它和它的答案是有帮助的,但我仍然觉得我不完全理解使用非类型模板参数背后的用法和理论.它们提供了许多有用的例子,说明它何时被使用,但没有一个真正阐明非类型模板参数背后的理论.
我有兴趣在示例中不具体知道,但更广泛地说,为什么我倾向于使用非类型模板参数而不仅仅是常规函数参数.
我知道它们是在编译时确定的,并且每个新调用都会创建一个具有非类型模板参数的确定值的新函数.那么,为什么我只想在函数中输入我想要的参数并且具有相同的结果(假设只有一个编译函数)时,我想要创建相同函数的许多不同实例.
从本质上说,为什么要我倾向于做#1,而不是#2,如根据的最后一节这个页面的cplusplus.com?
#1:
template <class T, int N>
T fixed_multiply (T val)
{
return val * N;
}
int main() {
std::cout << fixed_multiply<int,2>(10) << '\n';
std::cout << fixed_multiply<int,3>(10) << '\n';
}
Run Code Online (Sandbox Code Playgroud)
#2:
template <class T>
T fixed_multiply (T val, int N)
{
return val * N;
}
int main() {
std::cout << fixed_multiply<int>(10, 2) << '\n';
std::cout << fixed_multiply<int>(10, 3) << '\n';
}
Run Code Online (Sandbox Code Playgroud)
此外,是否会有任何性能优势?是否有任何常见的应用程序可以从使用非类型模板参数中受益,或者这是一个在特定应用程序中使用的高技术参数,以产生特定的结果?
编辑:由于某种原因,这被标记为重复,第一段解释了我的类似问题的原因.