【发布时间】:2020-05-25 18:12:06
【问题描述】:
我正在尝试编写一个泛型函数,其参数包含模板类型上的多个转换,例如:
#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。
这是预期的吗,有什么方法可以实现吗?
【问题讨论】:
-
_T_是在所有上下文中为 C++ 实现保留的标识符,因为它以一个下划线开头,后跟一个大写字母。使用这样的标识符会导致未定义的行为。我建议你不要使用它。 (只是T是一个常用的模板参数名称,在这里就可以了。) -
我不确定你是如何设法得到你的替代方案来推断类型的。
_T_在这种情况下仍处于非推断上下文中,它应该给出相同的错误消息。 -
无关:
int main( void )-->int main()- C++ 不是 C. -
@walnut 没错,坏习惯很难改
标签: c++ templates type-inference typetraits template-argument-deduction