简体   繁体   中英

Template function deduction fail on std::conditional argument

Please, before marking this as a duplicate of This question read the entirety of the post

This piece of code fails to compile, with a template deduction error:

#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;
}

I understand the point that was made in the question i linked above, which is that "the condition which allows to choose the type to be deduced depends on the type itself", however, why would the compiler fail in the specific case i provided as the condition here seems to be fully independent from the type, or is there something i'm missing?

I would be more than happy if someone could refer to a section of the c++ standard that would allow me to fully understand this behaviour.

As the linked question, TYPE is non deducible. MyType<TYPE> is actually XXX<TYPE>::type .

You have several alternatives, from your code, I would say one of

  • Bar no longer template:

     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 (or 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; } };

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM