Decltype (auto),尾随返回type和sfinae:可以混合使用吗?
decltype(auto), trailing return type and sfinae: can we mix them?
考虑以下代码:
auto f() -> decltype(auto) { /* do whatever you want here */ }
int main() { f(); }
推导返回类型,并使用decltype(auto)
作为尾返回类型。
下面的代码是稍微修改过的版本(实际上是):
struct S { static void f() {} };
struct T {};
template<typename U>
auto f(int) -> decltype(U::f(), void()) {
// do whatever you want here
}
template<typename>
auto f(char) -> decltype(auto) {
// do whatever you want here
}
int main() {
f<S>(0);
f<T>(0);
}
如果你参加考试,这个函数:
template<typename U>
auto f(int) -> decltype(U::f(), void()) {
// do whatever you want here
}
问题是:是否有可能使用尾部返回类型来执行sfinae,并且仍然推导出返回类型?
我指的是像下面这样的代码(当然,这不起作用):
template<typename U>
auto f(int) -> decltype(U::f(), auto) {
// do whatever you want here
}
注意:我不是在寻找涉及模板参数的替代方法,我知道它们,我只是想知道如果这个是一个可行的解决方案。
decltype(auto)
是一个不可分割的结构(几乎就像decltype_auto
一样是一个关键字)。除此之外,auto
不能用作decltype(x)
内部的独立实体,因为这会阻止x
成为有效的表达式。
您可以为函数添加另一个类型为void(*)()
的参数,并为其指定一个尾随返回类型的lambda作为默认参数,以便SFINAE可以通过lambda:
template<typename U>
decltype(auto) f(int, void(*)() = []()->decltype(U::f(), void()) {})
{
// do whatever you want here
}
不是答案,而是使用void_t的可能解决方法。
至少和你想做的一样DRY:
template<typename... Ts> struct make_void { typedef void type;};
template<typename... Ts> using void_t = typename make_void<Ts...>::type;
struct S { static int f() { return 3; } };
struct P { static int p() { return 4; } };
struct T {};
template<typename U, void_t<decltype(U::f())>* = nullptr >
auto f(int) -> decltype(auto)
{
// do whatever you want here
std::cout << "f1n";
return U::f();
}
template<typename U, void_t<decltype(U::p())>* = nullptr >
auto f(int) -> decltype(auto)
{
// do whatever you want here
std::cout << "f3n";
return U::p();
}
template<typename>
auto f(char) -> decltype(auto) {
std::cout << "f2n";
// do whatever you want here
}
int main() {
std::cout << f<S>(0) << 'n';
std::cout << f<P>(0) << 'n';
f<T>(0);
}
相关文章:
- 为什么使用SFINAE而不是函数重载
- 如何使用模板函数的函数签名进行SFINAE
- 数据成员SFINAE的C++17测试:gcc vs clang
- 使用在用于SFINAE的void_t中具有参数的方法
- 混合组合和继承的C++问题
- 在混合代码库中将C转换为C++时出现许多包含错误
- 编译器如何在使用SFINAE的函数和标准函数之间确定两者是否可行
- D3D11-将混合权重和索引传递到顶点着色器
- 提供与TMP和SFINAE的通用接口
- "Inverse SFINAE"避免模棱两可的过载
- 表达式 SFINAE:如何根据类型是否包含具有一个或多个参数的函数来选择模板版本
- 如何在儿童类中使用SFINAE
- 使用 SFINAE 作为模板参数的编译时递归
- C++分数混合比较运算符错误
- 使用 SFINAE 设计模板方法
- 与SFINAE支票交朋友
- C++许多 SFINAE 风格的过载
- 是否可以混合使用SFINAE和模板专业化?
- 将CRTP与SFINAE混合
- Decltype (auto),尾随返回type和sfinae:可以混合使用吗?