具有多个转换的模板参数推导
Template argument deduction with multiple transformations
我正在尝试编写一个泛型函数,其中包含一个参数,其中包含模板类型的多个转换,例如:
#include <iostream>
#include <string>
#include <type_traits>
template< typename _T_ >
void foo
(
const std::basic_string< typename std::remove_cv< typename std::remove_extent< _T_ >::type >::type > & str
)
{
std::cout << str << std::endl;
}
int main( void )
{
foo< char const [ 3 ] >( "abc" ); // OK
foo( "abc" ); // Cannot deduce template argument
return 0;
}
遗憾的是,编译器无法推断出正确的类型。
使用最新版本的 Clang、GCC 和 MSVC 进行测试。
有趣的是,编译器似乎能够通过一个转换来推断:
const std::basic_string< typename std::remove_extent< _T_ >::type > & str
显然,上面的例子失败了,因为const
,因此需要在remove_extent
之后进行remove_cv
。
这是意料之中的吗,有什么办法可以实现这一目标吗?
包含限定 ids 的复杂名称是 C++ 中的非推导上下文。 在
foo< char const [ 3 ] >( "abc" );
T
提供模板参数。 在
foo( "abc" );
模板参数T
无法推导(函数参数与模板参数是分开的,因此不会从"abc"
推导出T
(。
一种解决方案是先推导模板参数,然后在参数为const CharT*
时构造basic_string
:
template <class CharT>
void foo(const std::basic_string<CharT>& string)
{
// ...
}
template <class CharT>
void foo(const CharT* p)
{
std::basic_string<CharT> s{p};
foo(s);
}
另一种解决方案是简单地依靠类模板参数推导来处理这两种情况:
template <class Arg>
void foo(Arg&& arg)
{
std::basic_string s{std::forward<Arg>(arg)};
// ...
}
也许你可以在模板参数列表中构建类型,并在函数参数列表中T
作为参考
template<typename T, typename U = const std::basic_string<std::remove_cv_t<std::remove_extent_t<T>>>>
void foo
(
T& t // deducible context
)
{
U& u = t;
std::cout << u << std::endl;
}
戈博尔特演示
相关文章:
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 如何将向量中的可变参数转换为参数的持有者?
- c++ 构造函数 将 1 个字符串参数转换为 3 个属性
- 将空*参数转换为各种类型的参数是UB吗?
- 将可变参数模板参数转换为 JSON 字符串
- C++ 如何将函数参数转换为字符串
- 功能指针参数参数转换为const
- 避免对模板运算符过载的隐式参数转换
- 将C 方法参数转换为模板参数会因编译错误而失败
- 将参数转换为lpwstr createProcess
- 在与时间一起使用 srand 时,如果我没有time_t参数明确地将参数转换为无符号的 int 参数,这有关系吗?
- 将C++整型模板参数转换为整型"longer"型
- 将参数转换为目标类型时,复制用于直接初始化的构造函数省略
- 将命令行参数转换为qimage
- 将可变数量的参数转换为明确的数量
- SDL 方法,参数转换
- 通过错误检查将参数转换为整数
- 功能参数转换为儿童类C
- 参数转换在课堂上
- 在窗口上将格式化的 C 字符串和参数转换为 wstring