有没有办法为模板化函数声明类型名?
Is There a Way to Declare a typename for a Templatized Function?
所以,我有 (我知道它很难看。)
虽然我的意图不是默认模板参数,但我的意图是创建一个派生自 T
的 typename
,可以在用户无法分配的 caster
中使用到.
我的问题是如何为用户无法作为参数传递的模板化函数创建 typename
?
举个例子:
template <typename T>
typename R = std::conditional<sizeof(T) == 4, char, short>;
R foo(T bar){return R(bar);}
显然这段代码无法编译,但这是我想要完成的行为。函子是唯一的方法吗?
一种可能性是使用 using
类型别名而不是 typename
。以下代码在我测试的编译器上编译(记得启用 -std=c++11
标志)。
#include <type_traits>
#include <iostream>
// C++11
template <typename T>
using R = typename std::conditional<sizeof(T) == 4, char, short>::type;
template <typename T>
R<T> foo(T bar){return R<T>(bar);}
int main() {
std::cout << foo(13.0) << std::endl;
return 0;
}
在C++14中,可以使用conditional_t
trait,更加简单。
// C++14
template <typename T>
using R = std::conditional_t<sizeof(T) == 4, char, short>;
在 C++14 中,这可以使用 return 类型推导优雅地解决。
// C++14
#include <type_traits>
template <typename T>
decltype(auto)
foo(T bar)
{
using R = std::conditional_t<sizeof(T) == 4, char, short>;
return static_cast<R>(bar);
}
在 C++11 中,您必须重复类型计算。
// C++11
#include <type_traits>
template <typename T>
typename std::conditional<sizeof(T) == 4, char, short>::type
foo(T bar)
{
using R = typename std::conditional<sizeof(T) == 4, char, short>::type;
return static_cast<R>(bar);
}
这可以通过使用 decltype
来确定类型来缩短一点。
// C++11
#include <type_traits>
template <typename T>
typename std::conditional<sizeof(T) == 4, char, short>::type
foo(T bar)
{
using R = decltype(foo(bar));
return static_cast<R>(bar);
}
但坦率地说,使用简单的默认类型参数有什么问题?
// C++11
#include <type_traits>
template <typename T,
typename R = typename std::conditional<sizeof(T) == 4, char, short>::type>
R
foo(T bar)
{
return static_cast<R>(bar);
}
请注意,我已将 return
语句中 R
的值初始化替换为 static_cast
以消除编译器关于缩小转换的警告。不过,您确定这就是您想要的吗?
所以,我有
虽然我的意图不是默认模板参数,但我的意图是创建一个派生自 T
的 typename
,可以在用户无法分配的 caster
中使用到.
我的问题是如何为用户无法作为参数传递的模板化函数创建 typename
?
举个例子:
template <typename T>
typename R = std::conditional<sizeof(T) == 4, char, short>;
R foo(T bar){return R(bar);}
显然这段代码无法编译,但这是我想要完成的行为。函子是唯一的方法吗?
一种可能性是使用 using
类型别名而不是 typename
。以下代码在我测试的编译器上编译(记得启用 -std=c++11
标志)。
#include <type_traits>
#include <iostream>
// C++11
template <typename T>
using R = typename std::conditional<sizeof(T) == 4, char, short>::type;
template <typename T>
R<T> foo(T bar){return R<T>(bar);}
int main() {
std::cout << foo(13.0) << std::endl;
return 0;
}
在C++14中,可以使用conditional_t
trait,更加简单。
// C++14
template <typename T>
using R = std::conditional_t<sizeof(T) == 4, char, short>;
在 C++14 中,这可以使用 return 类型推导优雅地解决。
// C++14
#include <type_traits>
template <typename T>
decltype(auto)
foo(T bar)
{
using R = std::conditional_t<sizeof(T) == 4, char, short>;
return static_cast<R>(bar);
}
在 C++11 中,您必须重复类型计算。
// C++11
#include <type_traits>
template <typename T>
typename std::conditional<sizeof(T) == 4, char, short>::type
foo(T bar)
{
using R = typename std::conditional<sizeof(T) == 4, char, short>::type;
return static_cast<R>(bar);
}
这可以通过使用 decltype
来确定类型来缩短一点。
// C++11
#include <type_traits>
template <typename T>
typename std::conditional<sizeof(T) == 4, char, short>::type
foo(T bar)
{
using R = decltype(foo(bar));
return static_cast<R>(bar);
}
但坦率地说,使用简单的默认类型参数有什么问题?
// C++11
#include <type_traits>
template <typename T,
typename R = typename std::conditional<sizeof(T) == 4, char, short>::type>
R
foo(T bar)
{
return static_cast<R>(bar);
}
请注意,我已将 return
语句中 R
的值初始化替换为 static_cast
以消除编译器关于缩小转换的警告。不过,您确定这就是您想要的吗?