【问题标题】:SFINAE on array initialization in VS10SFINAE 关于 VS10 中的数组初始化
【发布时间】:2019-02-22 13:43:25
【问题描述】:

cppreference/variant(4) 上的转换构造函数描述如下:

转换构造函数。构造一个变体,该变体包含替代类型T_j,如果同时在作用域内对来自Types... 的每个T_i 存在虚函数F(T_i) 的重载,则该变体将由表达式F(std::forward<T>(t)) 的重载决议选择,除了:

  • 仅当声明 T_i x[] = { std::forward<T>(t) }; 对某些发明变量 x 有效时才考虑重载 F(T_i)
  • 如果 T_i 是(可能是 cv-qualified)bool,则仅当 std:remove_cvref_t<T> 也是 bool 时才考虑 F(T_i)

由于我与 Visual Studio 2010 相关联,但仍想拥有一个标准变体,因此我自己实现了一个。我遇到的问题以及我在这里寻求解决方案的问题是如何在 VS10 中实现第一个要点?如何丢弃假想函数F(T_i)如果表达式的重载

T_i x[] = { std::forward<T>(t) };

格式不正确?

在 VS15 中我可以写:

template<class T> using array_t = T[];

template<class UserType, class T_i, class = void>
struct Single_FUN_T_i {
    using type = void(*)();
};

template<class UserType, class T_i>
struct Single_FUN_T_i<UserType, T_i,
    decltype( array_t<T_i>{ std::declval<UserType>() }, void() )> {
    //        ^^ Here I check whether T_i[]{ declval<T>() } compiles
    using type = T_i(*)(T_i);
};

但是在 VS10 中这不起作用,因为表达式 array_t&lt;T_i&gt;{ std::declval&lt;UserType&gt;() } 似乎不受支持(我知道别名模板也不起作用,但这不是问题)。

【问题讨论】:

    标签: c++ visual-studio-2010 sfinae


    【解决方案1】:

    我认为这可能会让您走得更远。不要使用数组初始化,而是使用 declval 实例化一个数组并尝试在其中插入元素。

    // TestSfinae.cpp : 这个文件包含'main'函数。程序执行从那里开始和结束。 //

    #include <iostream>
    #include <utility>
    #include <iostream>
    #include <string>
    #include <boost/utility/declval.hpp>
    
    template<class A, class B, class = void>
    struct X {
        std::string msg;
        X():msg("Fail"){};
    };
    
    template<class A, class B>
    struct X<A, B, decltype(boost::declval<A[]>()[0]=boost::declval<B>(), void()) > 
    {
        std::string msg;
        X():msg("Pass"){};
    };
    
    int main(){
        X<int,int> x;
        std::cerr << x.msg << std::endl;;
    
        X<int,std::string> y;
        std::cerr << y.msg << std::endl;;
    
    }
    

    预期的结果是

    Pass
    Fail
    

    【讨论】:

      【解决方案2】:

      不幸的是,我认为,我无法用 VS10 解决这个问题。这是因为 the aggregate initilization T object[]{args...} 仅在 C++11 之后可用,而不是 VS10 的一部分。并且要在聚合初始化上执行 SFINAE,我不能写 decltype(T x[]= {arg}),但必须像我的示例中那样写 decltype(array_t&lt;T&gt;{arg})

      【讨论】:

        猜你喜欢
        • 2022-11-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-17
        • 2011-02-15
        • 1970-01-01
        • 2013-01-20
        • 1970-01-01
        相关资源
        最近更新 更多