std::conditional 参数上的模板函数推导失败

Template function deduction fail on std::conditional argument

请在将此标记为 问题的副本之前阅读整个 post

这段代码编译失败,模板推导错误:

#include <iostream>
#include <type_traits>

template<typename T = float, int N>
class MyClass
{
    public:
        template<typename DATA_TYPE>
        using MyType = std::conditional_t<(N>0), DATA_TYPE, double>;
        
        MyType<T> Var;
        
        void Foo()
        {
           Bar(Var);
        }
        
        template<typename TYPE>
        void Bar(MyType<TYPE> Input)
        {
            std::cout << typeid(Input).name() << std::endl;
        }
};

int main()
{
    MyClass<float, 1> c;
    c.Foo();
    return 0;
}

我理解我在上面链接的问题中提出的观点,即“允许选择要推导的类型的条件取决于类型本身”,但是,为什么编译器会在我作为条件提供的具体情况似乎完全独立于类型,还是我遗漏了什么?

如果有人可以参考 c++ 标准的一部分,让我完全理解这种行为,我会非常高兴。

作为链接的问题,TYPE 是不可推导的。 MyType<TYPE> 实际上是 XXX<TYPE>::type.

你有几种选择,根据你的代码,我会说其中之一

  • Bar 不再是模板:

    template<typename T = float, int N>
    class MyClass
    {
        public:
            template<typename DATA_TYPE>
            using MyType = std::conditional_t<(N>0), DATA_TYPE, double>;
    
            MyType<T> Var;
    
            void Foo()
            {
               Bar(Var);
            }
    
            void Bar(MyType<T> Input)
            {
                std::cout << typeid(Input).name() << std::endl;
            }
    };
    
  • requires(或 SFINAE/specialization for pre-c++20):

    template<typename T = float, int N>
    class MyClass
    {
        public:
            template<typename DATA_TYPE>
            using MyType = std::conditional_t<(N>0), DATA_TYPE, double>;
    
            MyType<T> Var;
    
            void Foo()
            {
               Bar(Var);
            }
    
            template<typename TYPE>
            void Bar(TYPE Input) requires(N > 0)
            {
                std::cout << typeid(Input).name() << std::endl;
            }
            void Bar(double Input) requires(N <= 0)
            {
                std::cout << typeid(Input).name() << std::endl;
            }
    };