指定默认模板参数

3

假设我有一个模板函数如下:

template<typename T, typename DType=uint32_t>
void fun(T a) {
    //...
    // DType is used inside
}

如何指定 DType 的类型,但让编译器推断出 T 的类型呢?类似这样:

fun<DType=int32_t>(static_cast<std::string>(s));
2个回答

6

按照您所写的方式,是无法实现的。最好的方法是交换类型,并让编译器推断T的类型,例如:

template<typename DType=uint32_t, typename T>
void fun(T a) {
    //...
    // DType is used inside
}

编译器将据此推断T的类型。
示例:
#include <iostream>

template<typename DType = uint32_t, typename T>
void fun(T a) {
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}

int main()
{
    fun<char>(42); // T is deduced as int, DType as char
}

正如评论中@T.C.所提到的:“与类模板不同,函数模板的默认模板参数无需在尾部模板参数上。”

在Coliru上实时查看


@BoundaryImposition 谢谢!在看到这个问题之前,我从来没有想过我们实际上可以这样做! - vsoftco
你不需要那个默认设置。这种编程语言并不疯狂。 - T.C.
@T.C 你如何指定一个非默认的 DType 类型? - vsoftco
3
template<typename DType=uint32_t, typename T> void fun(T); 函数模板的默认模板参数不像类模板一样只能出现在模板参数列表的最后一个位置,可以出现在任意位置。 - T.C.
@T.C. 现在C++17通过ctor具有类类型推导,我们是否能够对类执行相同的操作?即,非尾随默认类型参数? - vsoftco
显示剩余2条评论

0

我能想到的最好的方法是添加一个未使用的DType参数

#include <iostream>

template<typename T, typename DType = uint32_t>
void fun(T a, DType = 0) {
    //...
    // DType is used inside
}

int main ()
 {
   char s[] = "abc";

   fun(static_cast<std::string>(s));
   fun(static_cast<std::string>(s), int32_t{0});
 }

显然,这仅适用于某些DType;例如,如果DType固定为void。
fun<std::string, void>(static_cast<std::string>(s));

你会得到一个编译错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接