gpt4 book ai didi

c++ - 模棱两可的模板怪异

转载 作者:可可西里 更新时间:2023-11-01 17:43:43 25 4
gpt4 key购买 nike

我有以下代码(抱歉代码块太大,但我无法再缩小范围)

template <bool B>
struct enable_if_c {
typedef void type;
};

template <>
struct enable_if_c<false> {};

template <class Cond>
struct enable_if : public enable_if_c<Cond::value> {};

template <typename X>
struct Base { enum { value = 1 }; };

template <typename X, typename Y=Base<X>, typename Z=void>
struct Foo;

template <typename X>
struct Foo<X, Base<X>, void> { enum { value = 0 }; };

template <typename X, typename Y>
struct Foo<X, Y, typename enable_if<Y>::type > { enum { value = 1 }; };

int main(int, char**) {
Foo<int> foo;
}

但它无法用 gcc (v4.3) 编译

foo.cc: In function ‘int main(int, char**)’:
foo.cc:33: error: ambiguous class template instantiation for ‘struct Foo<int, Base<int>, void>’
foo.cc:24: error: candidates are: struct Foo<X, Base<X>, void>
foo.cc:27: error: struct Foo<X, Y, typename enable_if<Y>::type>
foo.cc:33: error: aggregate ‘Foo<int, Base<int>, void> foo’ has incomplete type and cannot be defined

好吧,所以这是模棱两可的。但我没想到它会成为一个问题,因为在使用特化时它几乎总是会有些歧义。但是,此错误仅在将类与 enable_if<...> 一起使用时触发。 ,如果我将其替换为如下类,则没有问题。

template <typename X, typename Y>
struct Foo<X, Y, void > { enum { value = 2 }; };

为什么这个类不会引起歧义而其他类会引起歧义?对于具有 true::value 的类,这两者不是一回事吗?无论如何,感谢任何关于我做错了什么的提示。

感谢您的回答,我真正的问题(让编译器选择我的第一个特化)通过替换 struct Foo<X, Base<X>, void> 解决了与 struct Foo<X, Base<X>, typename enable_if< Base<X> >::type >这似乎按照我想要的方式工作。

最佳答案

你的问题的要点是你有:

template <typename X, typename Y, typename Z>
struct Foo {};

template <typename X>
struct Foo<X, Base<X>, void> {}; // #1

template <typename X, typename Y>
struct Foo<X, Y, typename whatever<Y>::type> {}; // #2

而你正试图将其匹配到

Foo<int, Base<int>, void>

显然,两个专业匹配(第一个与 X = int ,第二个与 X = int, Y = Base<int> )。

根据标准,第 14.5.4 节,如果有更多匹配的特化,则构建它们之间的偏序(如 14.5.5.2 中所定义)并使用最特化的。但是,就您而言,两者都不比另一个更专业。 (简单地说,一个模板比另一个模板更专业,如果你可以用某种类型替换后一个模板的每个类型参数,结果得到前一个模板的签名。另外,如果你有 whatever<Y>::type 并替换 Y使用 Base<X> 你得到 whatever<Base<X> >::type 而不是 void ,即没有执行处理。)

如果你替换#2

template <typename X, typename Y>
struct Foo<X, Y, void > {}; // #3

然后候选集再次包含两个模板,但是,#1 比 #3 更专业,因此被选中。

关于c++ - 模棱两可的模板怪异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1166822/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com