我想知道,如果在C ++ 0x中可以创建一个静态类型的变体,(表现得像auto):
variant<int, bool, std::string> v = 45;
当我们将v赋值给int以外的值时,它不会编译:
v = true; //Compile error
到目前为止,我还没有找到任何优雅的解决方案。
答案 0 :(得分:6)
此代码在我的机器上使用Boost.Variant和g ++ 4.5编译C ++ 98和C ++ 0x。你想自己实现变体类型吗?然后你可以看一下Boost实现。
如果您想要/获得/上述行为,您可以这样做:
auto v = 45;
static_assert(std::is_same<decltype(v), bool>
|| std::is_same<decltype(v), int>
|| std::is_same<decltype(v), std::string>,
"v must be int, bool or string");
这应该与你描述的完全相同。
以下实施Clintons建议:
template <typename T, typename... Args>
struct has_type;
template <typename T, typename Head, typename... Args>
struct has_type<T, Head, Args...>
{
static const bool value = std::is_same<T, Head>::value
|| has_type<T, Args...>::value;
};
template <typename T>
struct has_type<T> : std::false_type
{};
template <typename... Args, typename T>
T&& check_type (T&& t)
{
static_assert(has_type<T, Args...>::value, "check_type");
return std::move(t);
}
您只需<memory>
和<type_traits>
即可获得完整转发和整数提升的正确行为。
答案 1 :(得分:2)
我认为,这是不可能的。
创建对象后,其静态类型不包含与对象初始化相关的任何信息。无关紧要,int或bool用于初始化,变量的类型是相同的:
variant<int, bool, std::string>
赋值运算符只能在运行时分析内容,如果需要则抛出异常。
答案 2 :(得分:1)
不,我认为你不能在编译时这样做。
您可以使用enable_if或类似功能启用或禁用一组赋值运算符,但它们是每种类型,而不是每个实例。在一个编译单元中编译v = true时,我们怎么知道你在另一个编译单元中使用了什么构造函数?