C++ 在C+中创建静态类型的变量+;0x

C++ 在C+中创建静态类型的变量+;0x,c++,c++11,variant,template-meta-programming,C++,C++11,Variant,Template Meta Programming,我想知道,在C++0x中是否可以创建一个静态类型的变量(其行为类似于auto): 到目前为止,我还没有找到任何优雅的解决方案 这段代码在我的机器上用Boost.Variant和g++4.5编译,用于C++98和C++0x。您想自己实现一个变体类型吗?然后您可以研究Boost实现 如果你想/获得/以上行为,你可以这样做: auto v = 45; static_assert(std::is_same<decltype(v), bool> || std::is

我想知道,在C++0x中是否可以创建一个静态类型的变量(其行为类似于auto):


到目前为止,我还没有找到任何优雅的解决方案

这段代码在我的机器上用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");
autov=45;
静态断言(std::是否相同
||std::是一样的吗
||std::是一样的,
“v必须是int、bool或string”);
这应该相当于你所描述的

以下是克林顿的建议:

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);
}
模板
结构具有_类型;
模板
结构具有\u类型
{
静态常量布尔值=标准::是否相同::值
||has_type::value;
};
模板
结构具有\u类型:std::false\u类型
{};
模板
T&T检查类型(T&T)
{
静态_断言(has_type::value,“check_type”);
返回std::move(t);
}

你只需要
,就可以获得完美的转发和整数升级的正确行为。

我认为,这是不可能的

创建对象后,其静态类型不包含任何与对象初始化相关的信息。不管是int还是bool用于初始化,变量的类型是相同的:

variant<int, bool, std::string>
变体

赋值运算符只能在运行时分析内容,如果需要,可以抛出异常。

不,我认为您不能在编译时这样做


您可以使用enable_if或类似工具启用或禁用一组赋值运算符,但将按类型而不是按实例启用或禁用。当在一个编译单元中编译v=true时,我们怎么知道在另一个编译单元中使用了什么构造函数呢?

是的,我忘了提到它,我想实现它,但与boost解决方案不同,我的变体无法更改它的类型。那么这是不可能的。您无法在编译时设置对象参数。你为什么要这么做?事实上,C++0x
auto
-关键字加上一些额外的
decltype
-魔法可能就是你想要的,我将把它添加到答案中。Filmers的解决方案就是最好的选择。如果你想让它看起来更好,我建议“自动v=检查类型(45)”。Check_类型只会转发它的参数,但如果它不是枚举类型之一,则会转发静态_断言。创建check_type类我相信是可能的,它只需要一些模板魔法。我实现了上面的建议:)C++0x ftw\o/是否要阻止编译
v=true
或是它没有编译的问题?是的,我想阻止编译v=True。如果我们使用带有auto关键字的宏,并使用static_assert检查类型是否在提供的类型集中(使用std::is_same或boost::is_same)。请参阅我(编辑)的答案。我不认为你可以用它来制作宏,它的行为就像一个类型。@Simon:也许我们有时可以让它工作,但一般来说不行。如果您有
外部变量v;v=真,编译器如何知道v是如何构造的?如果您稍后更改另一个模块怎么办?
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);
}
variant<int, bool, std::string>