SFINAE在VS10中进行阵列初始化

问题描述 投票:0回答:2

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

转换构造函数。构造一个变体持有替代类型T_j,如果在范围内同时存在来自范围内F(std::forward<T>(t))的每个F(T_i)的虚函数T_i的重载,则将通过重载决策选择表达式Types...,除了:

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

由于我与Visual Studio 2010绑定,但仍希望有一个std-variant,我自己实现了一个。我遇到的问题以及我要求解决的问题是如何在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>() }似乎不受支持(我知道别名模板也不会工作,但这不是问题)。

c++ visual-studio-2010 sfinae
2个回答
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

0
投票

不幸的是,我认为,我无法用VS10解决这个问题。这是因为the aggregate initilization T object[]{args...}仅在C ++ 11之后可用,而不是VS10的一部分。要在聚合启动时做SFINAE我不能写decltype(T x[]= {arg})但是必须像我的例子那样写decltype(array_t<T>{arg})

© www.soinside.com 2019 - 2024. All rights reserved.