我可以使模板参数成为可选参数,例如函数参数的std :: optional吗?

时间:2019-08-05 20:06:27

标签: c++ c++17

我想要一个像这样的模板:

template<typename T, class U, U SOME_NON_TYPE_ARG>
func1()
{
  if SOME_NON_TYPE_ARG is given
  {
    // do something special
  }
   // do something with the SOME_NON_TYPE_ARG value.
}

我希望函数主体取决于是否提供了SOME_NON_TYPE_ARG。

我尝试将U设置为std :: optional,但是显然,optional不能是非类型模板参数的类型。有什么办法可以在C ++ 17中实现?

这是我的解决方法之一,但这更像是hack,有什么更好的方法吗?

#include <type_traits>
#include <iostream>

template<typename T> constexpr std::optional<T> typed_nullopt = std::nullopt;
template <typename T, class U = const std::optional<T> &, U SOME_NON_TYPE_ARG = typed_nullopt<T> >
void test_optional_template(T a)
{
    if constexpr (SOME_NON_TYPE_ARG == typed_nullopt<T>)
    {
        std::cout << a << " we do not have non-type arg" << std::endl;
    }
    else
    {
        std::cout << a + SOME_NON_TYPE_ARG << std::endl;
    }

}
int main()
{
    test_optional_template<int, int, 3>(5);
    test_optional_template<int>(10);
}

输出将是:

8
10 we do not have non-type arg

2 个答案:

答案 0 :(得分:3)

重载函数:

template<typename T, class U>
void func1()
{
    // Do something
}

template<typename T, class U, U SOME_NON_TYPE_ARG>
void func1()
{
    // Do something else
    func1<T, U>();
}

答案 1 :(得分:2)

您可以这样做:

template <typename T, auto... Vs>
void func() {
    static_assert(sizeof...(Vs) <= 1);
    if constexpr (sizeof...(Vs) == 1) {
        constexpr auto V = [](auto X){ return X; }(Vs...);
        // do something with V
    }
}

func<int>()不会做任何特殊的事情,func<int, 1>()将退出V,因为1func<int, 1, 2>()格式错误。