SFINAE关于VS10中的数组初始化

时间:2019-02-22 13:43:25

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

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

  

转换构造函数。构造一个包含替代类型T_j的变体,如果F(std::forward<T>(t))中每个F(T_i)的虚函数T_i都有重载,则可以通过重载解析为表达式Types...选择该变体。 1}}同时作用域,除了:

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

由于我与Visual Studio 2010紧密联系,但仍然希望拥有一个std变量,因此我自己实现了一个。我要解决的问题是,如何在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<T_i>{ std::declval<UserType>() }(我知道别名模板也不会起作用,但这不是问题)。

2 个答案:

答案 0 :(得分:0)

我认为这可以使您更进一步。不要使用数组初始化,而要使用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

答案 1 :(得分:0)

不幸的是,我认为我无法使用VS10解决此问题。这是因为the aggregate initilization T object[]{args...}仅从C ++ 11开始可用,但尚未成为VS10的一部分。为了对聚合初始化进行SFINAE,我不能写decltype(T x[]= {arg}),但必须像我的示例那样写decltype(array_t<T>{arg})