decltype(自动),尾随返回类型和sfinae:我们可以混合它们吗?

时间:2016-09-28 06:31:07

标签: c++ templates language-lawyer sfinae decltype

请考虑以下代码:

auto f() -> decltype(auto) { /* do whatever you want here */ }
int main() { f(); }

推导出返回类型,decltype(auto)用作尾随返回类型 以下代码略有修改(实际上, sfinae' d )版本:

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
}

注意:我没有寻找涉及模板参数的替代方法,我知道它们,我只是想知道这个是否是一个可行的解决方案。

3 个答案:

答案 0 :(得分:5)

decltype(auto)是一个不可分割的构造(几乎就像它是一个像decltype_auto这样的关键字)。除此之外,auto不能用作decltype(x)内的独立实体,因为这会阻止x成为有效的表达式。

答案 1 :(得分:0)

不是答案,而是使用void_t的可能解决方法。

至少它和你想做的干一样:

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 << "f1\n";
    return U::f();
}

template<typename U, void_t<decltype(U::p())>* = nullptr >
auto f(int) -> decltype(auto)
{
    // do whatever you want here
    std::cout << "f3\n";
    return U::p();
}

template<typename>
auto f(char) -> decltype(auto) {
    std::cout << "f2\n";
    // do whatever you want here
}

int main() {
    std::cout << f<S>(0) << '\n';
    std::cout << f<P>(0) << '\n';
    f<T>(0);
}

答案 2 :(得分:0)

您可以向函数添加另一个类型为void(*)()的参数,并为其指定一个带尾随返回类型的lambda作为默认参数,以便可以通过lambda应用SFINAE:

template<typename U>
decltype(auto) f(int, void(*)() = []()->decltype(U::f(), void()) {})
{
    // do whatever you want here
}