简体   繁体   English

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

[英]Overloading based on non-type template parameter

We are familiar with overloading based on function parameters. 我们熟悉基于函数参数的重载。 But why can't we have overloading based on non-type template parameters? 但为什么我们不能基于非类型模板参数进行重载? With such overloading, you don't have to add extra function parameters just for overloading purposes, which may have a negative impact on runtime performance. 通过这种重载,您不必为了重载而添加额外的函数参数,这可能会对运行时性能产生负面影响。 Alas, the following code does not compile: 唉,以下代码无法编译:

template <bool>
void func() {}

template <int>
void func() {}

int main() {
  func<0>();
}

The error message produced is 产生的错误消息是

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

Note that this may be more efficient than 请注意,这可能比效率更高

void func(bool) {}

void func(int) {}

Is there any problem in allowing this usage? 允许这种用法有什么问题吗?

Andrei Alexandrescu wrote about this in "Modern C++ Design", IIUC, and it looks like std::integral_constant can basically give nearly the effect you want, no? Andrei Alexandrescu在IIUC的“现代C ++设计”中写到了这一点,看起来std::integral_constant基本上可以给出你想要的效果,不是吗? What would be the major improvements over the following? 以下几项主要改进是什么? It basically allows to overload on (at least integral types of) constants. 它基本上允许重载(至少是整数类型的)常量。

#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;
}

If you are open to a bit of added syntax, you can use: 如果您对一些添加的语法持开放态度,可以使用:

// 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>();
}

Disclaimer 放弃

I have no idea whether this will perform better than calling func(true) . 我不知道这是否会比调用func(true)更好。

Why would you want to do that? 你为什么想这么做?

Templates are meant and designed for cases when the behavior of function is similar when having different types (such as finding a maximum value, as long as the operator '>' is supported for that type, you can find the maximum value. Doesn't matter whether it's an int or a float and such). 模板是针对具有不同类型的函数行为相似的情况而设计的(例如找到最大值,只要该类型支持运算符'>',就可以找到最大值。无论是int还是float等等。

You should just overload it and not worry about the impact, it is not as bad as you might think. 你应该超负荷而不用担心影响,它没有你想象的那么糟糕。 If the behavior is different enough between the functions, you shouldn't bother using templates 如果函数之间的行为不同,则不应该使用模板

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM