Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 可以写一个C++;用于检查构造函数的模板';谁的存在?_C++_Templates_Visual Studio 2013_Sfinae_Decltype - Fatal编程技术网

C++ 可以写一个C++;用于检查构造函数的模板';谁的存在?

C++ 可以写一个C++;用于检查构造函数的模板';谁的存在?,c++,templates,visual-studio-2013,sfinae,decltype,C++,Templates,Visual Studio 2013,Sfinae,Decltype,这个问题实际上是另一个用户提出的问题的后续问题,有一些很好的答案: 我想做这个问题中描述的事情,除了我想能够为构造函数做这件事。例如,考虑到这两种类型: class NormalType { public: NormalType() { std::cout << "NormalType::NormalType()" << std::endl; } }; class SpecialType { public: Specia

这个问题实际上是另一个用户提出的问题的后续问题,有一些很好的答案:

我想做这个问题中描述的事情,除了我想能够为构造函数做这件事。例如,考虑到这两种类型:

class NormalType
{
public:
    NormalType()
    {
        std::cout << "NormalType::NormalType()" << std::endl;
    }
};

class SpecialType
{
public:
    SpecialType()
    {
        std::cout << "SpecialType::SpecialType()" << std::endl;
    }
    SpecialType(int someArg)
    {
        std::cout << "SpecialType::SpecialType(int someArg)" << std::endl;
    }
};
但是如果我尝试测试一个没有定义我的目标构造函数的类型,由于缺乏SFINAE支持,那么在VS2013下就不会编译。也就是说,我还不认为这是不可能的,我认为可能有办法让它发挥作用,但到目前为止我还没有找到解决办法。有人看到我忽略的方法吗

这里有一些关于我需要什么的更多信息,以便接受答案作为此问题的解决方案:

  • 必须能够为任何给定类型解析
    has_special_constructor::value
    ,而无需为该特定类型编写额外代码

  • 我的主要目标是Visual Studio 2013,因此任何解决方案都必须在该环境下工作。我知道一个完全符合C++11标准的编译器可以更容易地处理这个问题,但是我正在寻找一个可以在我当前的目标编译器上运行的东西

  • 如果有人能提供一个在C++03编译器中工作的解决方案(即,没有任何C++11特性),我会接受这个方案,而不是使用C++11特性的方案

  • 在这一点上,我会满足于基于MSVC扩展的解决方案,因为在完全支持C++11之前,我可以使用预处理器回退到这种方法

模板
使用has_special_constructor=std::是可构造的;

可能的“C++03”版本:

模板
结构有特殊的构造函数{
类型1;
typedef结构{char[2];}two;
模板
结构虚拟{};
模板
静态1 f(虚拟*);
模板
静态二f(…);
静态常量布尔值=sizeof(f(0))==sizeof(一);
};

这适用于C++03模式下的g++4.4或更高版本。我把“C++03”放在可怕的引号里,因为这取决于表达式SFINAE,显然C++03的措辞似乎允许它,但直到C++11即将问世(GCC4.4于2009年发布)之前,没有一家主要的编译器供应商真正支持它,所以“纯”C++03是否允许它是有争议的…

Hah!就这么简单!我需要再次浏览C++11类型特征列表,并将它们提交到内存中。我刚刚花了3个小时寻找这个问题的解决方案。为了获得额外的分数*(嗯,不是真的,但如果我可以的话我会的!)你知道std::is_constructible是否可以在C++03编译器中模拟吗?@RogerSanders查看我的编辑。我相信您需要表达式SFINAE来实现这个,我想这是一种C++03。感谢C++03示例,尽管在VisualStudio中,即使在2013年,它也不走运。我尝试了几次修改它,但不是编译器出错,就是尝试的结果都不正确。我很确定,如果没有更好的SFINAE支持,没有C++11类型特征,就无法做到这一点。不过,对我的问题来说,C++03支持并不是必不可少的。谢谢,你帮了大忙。@RogerSanders甚至于Visual Studio 2013 expression。
template<class T>
class ConstructHelper
{
public:
    template<bool HasSpecialConstructor>
    static T Construct()
    {
        return T();
    }
    template<>
    static T Construct<true>()
    {
        return T(int(42));
    }
};
NormalType normalType = ConstructHelper<NormalType>::Construct<has_special_constructor<NormalType>::value>();
SpecialType specialType = ConstructHelper<SpecialType>::Construct<has_special_constructor<SpecialType>::value>();
template<class T>
struct has_special_constructor
{
    template<class S>
    struct calculate_value: std::false_type {};
    template<>
    struct calculate_value<decltype(T(int(42)))>: std::true_type {};

    static const bool value = calculate_value<T>::value;
};
template<class T>
using has_special_constructor = std::is_constructible<T, int>;
template <class T>
struct has_special_constructor {
  typedef char one;
  typedef struct { char _[2];} two;

  template <std::size_t>
  struct dummy {};

  template<class U>
  static one f(dummy<sizeof(U(42))>*);
  template<class>
  static two f(...);

  static const bool value = sizeof(f<T>(0)) == sizeof(one);
};