【发布时间】:2014-10-03 03:09:50
【问题描述】:
这个问题在精神上是另一个用户的这个问题的后续,它有一些很好的答案: Is it possible to write a template to check for a function's existence?
我想完全按照这个问题中的描述做,除了我希望能够为构造函数做这件事。例如,给定这两种类型:
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;
}
};
还有这个构造对象的辅助函数:
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>();
期望的结果是调用NormalType::NormalType(),并调用SpecialType::SpecialType(int someArg)。这里缺少的部分是关键的has_special_constructor 帮助器,它可以确定我们的特殊构造函数是否存在于给定类型。
我引用的上一个问题涉及检查一个给定的函数是否存在于一个类型上,并且提出了各种可行的解决方案。不幸的是,它们中的大多数依赖于能够获取目标方法的地址,并且根据 C++ 规范,您不能获取构造函数 (12.1.10) 的地址。在剩余的工作解决方案中,它们似乎都依赖于带有 decltype 的 SFINAE 和模板专业化中的任意表达式。这是解决此问题的一种简单方法,但不幸的是,我正在开发 Visual Studio 2013,它不能正确支持 C++11 SFINAE 规则,并且在“Visual Studio 14”的发布中仍然不支持.有了适当的 SFINAE 支持,我应该能够做到这一点,例如:
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;
};
但是如果我尝试测试一个没有定义我的目标构造函数的类型,由于缺乏 SFINAE 支持,它不会在 VS2013 下编译。也就是说,我还不相信这是不可能的,我认为可能有办法让它发挥作用,但到目前为止我还没有找到解决方案。有没有人看到我忽略的方法?
这里有一些关于我需要什么的更多信息才能接受答案作为这个问题的解决方案:
必须能够为任何给定类型解析
has_special_constructor<T>::value,而无需为该特定类型编写额外代码。我主要针对 Visual Studio 2013,因此任何解决方案都必须在该环境中工作。我知道完全符合 C++11 的编译器可以更轻松地解决这个问题,但我正在寻找可以在我当前的目标编译器上运行的东西。
如果有人可以提供在 C++03 编译器(IE,没有任何 C++11 功能)中工作的解决方案,我会接受使用 C++11 功能的解决方案。
此时我会接受基于 MSVC 扩展的解决方法,因为我可以使用预处理器回退到此方法,直到全面支持 C++11。
【问题讨论】:
标签: c++ templates visual-studio-2013 sfinae decltype