我们熟悉基于功能参数的重载。但是为什么我们不能基于非类型模板参数进行重载?有了这样的重载,您不必为了重载而添加额外的函数参数,这可能会对运行时性能产生负面影响。唉,以下代码无法编译:
template <bool>
void func() {}
template <int>
void func() {}
int main() {
func<0>();
}
产生的错误消息是
error: call of overloaded 'func()' is ambiguous
func<0>();
^
note: candidate: void func() [with bool <anonymous> = false]
void func() {}
^
note: candidate: void func() [with int <anonymous> = 0]
void func() {}
^
请注意,这可能比
更有效void func(bool) {}
void func(int) {}
允许这种用法有什么问题吗?
答案 0 :(得分:1)
Andrei Alexandrescu在&#34;现代C ++设计&#34;,IIUC中写到这一点,看起来std::integral_constant
基本上可以提供你想要的效果,不是吗?以下几项主要改进是什么?它基本上允许重载(至少是整数类型的)常量。
#include <type_traits>
using tt = std::integral_constant<bool, true>;
constexpr tt t;
using ft = std::integral_constant<bool, false>;
constexpr ft f;
void func(tt) {};
void func(ft) {};
int main()
{
func(t);
return 0;
}
答案 1 :(得分:1)
如果您对某些添加的语法持开放态度,可以使用:
// No default implementation.
template <typename T, T value> struct Impl;
// Implement the bool/true version
template <> struct Impl<bool, true>
{
void operator()() {}
};
// Implement the bool/false version
template <> struct Impl<bool, false>
{
void operator()() {}
};
// Implement the int version
template <int N> struct Impl<int, N>
{
void operator()() {}
};
template <typename T, T value>
void func()
{
Impl<T, value>()();
};
int main()
{
func<bool, true>();
func<int, 10>();
}
<强>声明强>
我不知道这是否会比调用func(true)
更好。
答案 2 :(得分:-2)
你为什么要这样做?
模板是为具有不同类型的函数行为相似的情况而设计的(例如找到最大值,只要该类型支持运算符'&gt;',就可以找到最大值无论是int还是float等都无关紧要。
你应该超负荷而不用担心影响,它没有你想象的那么糟糕。如果函数之间的行为不同,则不应该使用模板