为什么我们不能直接使用类模板来推导方法模板? SFINAE

问题描述 投票:2回答:1

此代码有效:

// g++ -std=c++11
// (or)
// clang++ -std=c++11

#include <iostream>

template <class T>
struct Tester
{
    template <class S = T, class = decltype(S())>
    static void Test (int && k)
    {
        std::cout << "Default constructible" << std::endl;
    }

    static void Test (...)
    {
        std::cout << "Not default constructible" << std::endl;
    }
};

struct HasDefaultConstructor
{
    HasDefaultConstructor() = default;
};

struct NoDefaultConstructor
{
    NoDefaultConstructor() = delete;
};

int main ()
{   
    Tester<HasDefaultConstructor>::Test(int());
    Tester<NoDefaultConstructor>::Test(int());

    return 0;
}

但是我想了解为什么我需要为间接模板推导S设置template <class S = T, class = decltype(S())>

我希望使用template <class = decltype(T())>更简单地执行此操作,但是在gcc中,这会导致错误的输出:对Test方法的所有调用都转到第一个;并在clang中导致错误call to deleted constructor of 'NoDefaultConstructor'(感谢HolyBlackCat在此处指出clang编译错误)。

为什么?强制我们间接引用类模板的编译器/ c ++标准的过程是什么?

c++ templates metaprogramming sfinae
1个回答
0
投票

这是因为您首先实例化模板类Tester。因此,要求class = decltype(T())成为模板类Tester<T>本身的要求。因此,如果不满意,则模板类格式错误。

间接推导template <class S = T, class = decltype(S())>将其转换为模板函数Test的需求,而不是整个类。

© www.soinside.com 2019 - 2024. All rights reserved.