基于非类型模板参数的重载

时间:2016-01-24 05:46:19

标签: c++ templates overloading language-lawyer

我们熟悉基于功能参数的重载。但是为什么我们不能基于非类型模板参数进行重载?有了这样的重载,您不必为了重载而添加额外的函数参数,这可能会对运行时性能产生负面影响。唉,以下代码无法编译:

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) {}

允许这种用法有什么问题吗?

3 个答案:

答案 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等都无关紧要。

你应该超负荷而不用担心影响,它没有你想象的那么糟糕。如果函数之间的行为不同,则不应该使用模板