Candidate template ignored because template argument could not be inferred

后端 未结 3 1666
执念已碎
执念已碎 2020-12-09 14:53

What is wrong with the following piece of code?

#include 

template
struct A {
    struct X { K p; };
    struct Y { K q; }         


        
相关标签:
3条回答
  • 2020-12-09 15:35

    The argument K in const typename A<K>::X is not deducible. Basically, everything left of a :: is not deducible (if :: separates a nested-name).

    It's trivial to see why it makes no sense to ask for deduction by running through this thought experiment:

    struct A { typedef int type; }
    struct B { typedef int type; }
    
    template <typename T> void foo(typename T::type);
    
    foo(5);   // is T == A or T == B ??
    

    There's no one-to-one mapping from types to nested types: Given any type (such as int), there could be many ambient types of which it is a nested type, or there needn't be any.

    0 讨论(0)
  • 2020-12-09 15:42

    Firstly, using :: for referencing a nested struct is not correct. The right way is to use A<K>.x, where x is a member of type X<K>. But for this to work, you need to declare two members x, y of type X<K> and Y<K>, respectively.

    Secondly, I think that a good practice is to separate the template declarations of struct X and struct Y from the declaration of struct A in order to avoid the nested struct declaration.

    In short, I would rewrite your code as followings:

    template<class K>
    struct X {
        K p;
    };
    
    template<class K>
    struct Y {
        K q;
    };
    
    template<class K>
    struct A {
        X<K> x;
        Y<K> y;
    };
    
    template<class K>
    void foo(const X<K>& x, const Y<K>& y) {
        std::cout << "A" << std::endl;
    }
    
    int main() {
        A<float> a;
        foo(a.x, a.y);
        return 0;
    }
    
    0 讨论(0)
  • 2020-12-09 15:53
    template<typename K>
    void foo(const typename A<K>::X& x, const typename A<K>::Y& y) {
        std::cout << "A" << std::endl;
    }
    

    K cannot been deduced, since it's in non-deduced context.

    n3337 14.8.2.5/4

    In certain contexts, however, the value does not participate in type deduction, but instead uses the values of template arguments that were either deduced elsewhere or explicitly specified. If a template parameter is used only in non-deduced contexts and is not explicitly specified, template argument deduction fails.

    n3337 14.8.2.5/5

    The non-deduced contexts are:

    — The nested-name-specifier of a type that was specified using a qualified-id.

    0 讨论(0)
提交回复
热议问题