我正在尝试设计一个包装器来使用一些特殊的逻辑来处理算术参数。
https://godbolt.org/z/zG959e5Pz
#include <stdio.h>
template <class T>
struct wrapper {
wrapper(const T& o): value(o) {}
T value;
};
void func(wrapper<int> a) {
printf("int: %d\n", a.value);
}
int main () {
func(1); // int: 1
func(1.0); // int: 1
}
但是,当我为
func
声明重载函数时,我遇到了编译错误。编译器似乎无法选择具体的重载函数。
#include <stdio.h>
template <class T>
struct wrapper {
wrapper(const T& o): value(o) {}
T value;
};
void func(wrapper<int> a) {
printf("int: %d\n", a.value);
}
void func(wrapper<double> a) {
printf("double: %.2f\n", a.value);
}
int main () {
func(1);
// func(1.1);
}
https://godbolt.org/z/YEo4c3E69
编译器错误
<source>: In function 'int main()':
<source>:18:9: error: call of overloaded 'func(int)' is ambiguous
18 | func(1);
| ~~~~^~~
<source>:9:6: note: candidate: 'void func(wrapper<int>)'
9 | void func(wrapper<int> a) {
| ^~~~
<source>:13:6: note: candidate: 'void func(wrapper<double>)'
13 | void func(wrapper<double> a) {
| ^~~~
我该如何修复它?
使构造函数成为模板,接受任何类型。然后使用 SFINAE 拒绝除
T
以外的类型。这将防止调用时隐式参数转换。
#include <concepts>
template <class T>
struct wrapper {
template <std::same_as<T> U = T>
wrapper(const U &o): value(o) {}
T value;
};
或 C++20 之前的版本:
template <class T>
struct wrapper {
template <typename U = T, std::enable_if_t<std::is_same_v<T, U>, std::nullptr_t> = nullptr>
wrapper(const U &o): value(o) {}
T value;
};