这是我的结构,它在创建变量时使用隐式转换。
#include <string>
#include <variant>
using namespace std;
using val = variant<int, string, double, bool, long, long long, long double>;
struct value
{
val innerVal;
value():innerVal(""){}
value(const val &c) : innerVal(c) {}
template <typename T>
operator T()
{
return get<T>(innerVal);
}
template <typename V>
value &operator=(const V &t)
{
innerVal = t;
return *this;
}
};
这就是我在构造变量时使用它的方式,它工作正常,但是当我将已创建的变量分配给
value
结构时,它会给出错误。
int main(int argc, char* argv[])
{
value h;
h = "String";
string m = h;// Here works fine
string b = "different";
b = h;//Here it gives error
}
编译错误
use of overloaded operator '=' is
ambiguous (with operand types
'std::__ndk1::string' (aka
'basic_string<char, char_traits<char>,
allocator<char> >') and 'value')
b = h;
我想隐式构造变量而不会遇到此错误,有人可以解释如何解决此问题。
分配
b = h
不明确,因为 std::string
具有不同的 operator=
。因为您有一个模板化转换运算符,所以您的编译不知道要采用哪个重载的 operator=
或 std::string
。
您可以限制
value
允许的转换类型,以仅允许隐式转换为成员 variant
的类型之一。以下结构体将使用折叠表达式提供一个布尔值,告诉我们类型 T
是否包含在 Type
的模板参数中:
template<typename, typename>
struct has_template_param;
template<typename T, template<typename ...> typename Type, typename ...Ts>
struct has_template_param<T, Type<Ts...>> {
static constexpr bool value = (... || std::is_same_v<T, Ts>);
};
然后可以使用 SFINAE 来约束模板化转换运算符:
template<typename T, typename = std::enable_if_t<has_template_param<T, val>::value>>
operator T() {
return std::get<T>(innerVal);
}
使用C++20概念,可以通过
更方便地完成template<typename T, typename Type>
concept has_param = has_template_param<T, Type>::value;
和
template<has_param<val> T>
operator T() {
return std::get<T>(innerVal);
}