候选模板被忽略,因为无法推断出模板参数

时间:2012-09-24 13:37:31

标签: c++ templates

以下代码有什么问题?

#include <iostream>

template<typename K>
struct A {
    struct X { K p; };
    struct Y { K q; };
};

template<typename K>
void foo(const typename A<K>::X& x, const typename A<K>::Y& y) {
    std::cout << "A" << std::endl;
}

int main() {
    A<float>::X x;
    A<float>::Y y;
    foo(x, y);  
}

clang给出以下错误消息:

17:2: error: no matching function for call to 'foo'
        foo(x, y);      
        ^~~
10:6: note: candidate template ignored: couldn't infer template argument 'K'
void foo(const typename A<K>::X& x, const typename A<K>::Y& y) {
     ^
1 error generated.

3 个答案:

答案 0 :(得分:48)

K中的参数const typename A<K>::X 不可扣除。基本上,::左边的所有内容都不可推导(如果::分隔嵌套名称)。

通过这个思想实验来了解为什么要求扣除是没有意义的,这是微不足道的:

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 ??

从类型到嵌套类型没有一对一的映射:给定任何类型(例如int),可能有许多环境类型,它是嵌套类型,或者不需要任何

答案 1 :(得分:8)

template<typename K>
void foo(const typename A<K>::X& x, const typename A<K>::Y& y) {
    std::cout << "A" << std::endl;
}

K无法推断,因为它位于non-deduced上下文中。

n3337 14.8.2.5/4

但是,在某些情况下, 该值不参与类型推导,而是使用模板参数的值 在其他地方推断或明确指定。 如果模板参数仅在非推导中使用 上下文并未明确指定,模板参数推断失败

n3337 14.8.2.5/5

未推断的上下文是:

- 使用qualified-id指定的类型的嵌套名称说明符。

答案 2 :(得分:0)

首先,使用::引用嵌套结构是不正确的。正确的方法是使用A<K>.x,其中x是类型X<K>的成员。但这要起作用,您需要声明两个成员x,类型yX<K>的{​​{1}}。

第二,我认为一种好的做法是将Y<K>struct X的模板声明与struct A的声明分开,以避免嵌套的struct声明。

简而言之,我将您的代码重写如下:

struct Y