给出代码
#include <type_traits>
template <auto I, class T>
struct C {};
template <auto I, class T>
void func(C<I, T> c) {}
struct C2 : C<0, int>, C<0u, long> {};
int main() {
static_assert(!std::is_same<C<0, int>, C<0u, long>>::value);
C2 c2;
func<0>(c2); // Error
return 0;
}
我收到了错误消息(来自GCC):
<source>:15:15: note: 'C<0, T>' is an ambiguous base class of 'C2'
15 | func<0>(c2);
| ^
当实例化(C<I, T>
和C<0, int>
)是明显不同的类型时,类模板(C<0u, long>
)为何会成为模棱两可的基类?
编辑:我忘了部分专业化。
答案 0 :(得分:2)
错误消息可能会稍微好一些。但是问题在于尝试进行重载解析。理论上可以从import random
player_decision = input("Do you want to roll the Dice ? Type y or n: ").lower()
if player_decision == "y":
game_on = True
else:
game_on = False
print("Thanks for your time!!")
while game_on is True:
print("Welcome")
roll_dice = input("Press R to roll the dice or Q to quit the game ").upper()
if roll_dice == "R":
def rolling():
outcome = random.randint(1, 7)
print(outcome)
rolling()
合成两个可能的重载:
C2
这是因为可以将类类型的自变量与接受其基数之一的模板进行匹配。模板参数推导能够推导基类的模板参数。
但是这里有一个问题:编译器只允许从模板合成一个重载,那么应该使用哪个基类进行合成?那是模棱两可的,因此会发生您的错误。编译器不知道应该使用哪个基类来进行void func(C<0, int> c) {}
void func(C<0u, long> c) {}
专业化的模板参数推导。从这个意义上说,这些基础是模棱两可的。
您的编辑没有太大变化。您指定了C
,但仍可以与0
参数匹配。为了匹配非类型模板参数,相应的模板参数必须是参数类型的转换后的常量表达式。 0u
是一个常量表达式,可以将其转换为0
常量表达式,反之亦然。因此,将0u
或什至0
指定为显式参数并不能解决歧义。
指定0u
或int
将解决歧义。这样我们可以重写:
long
然后致电
template <class T, auto I>
void func(C<I, T> ) {}
答案 1 :(得分:1)
当实例化(
C<I, T>
和C<0, int>
)是明显不同的类型时,类模板(C<0u, long>
)为何会成为模棱两可的基类?
它们是不同类型的事实是问题所在。 C2
继承自两者,并且模板func
接受两个基类-编译器应选择哪个基类?
您可以明确知道将c2
的哪一部分传递给func
时可以解决此问题:
func(static_cast<C<0, int>>(c2)); // Works fine now