C++ 确定是否存在没有功能测试宏的类型
我想在不使用功能测试宏的情况下确定类型是否存在。以下是使用宏的想法:C++ 确定是否存在没有功能测试宏的类型,c++,templates,types,C++,Templates,Types,我想在不使用功能测试宏的情况下确定类型是否存在。以下是使用宏的想法: namespace real { struct foo final { static constexpr const char* name = "real::foo"; }; } #define real_foo_ 314 struct my_foo final { static constexpr const char* name = "my_foo"; }; namespa
namespace real
{
struct foo final { static constexpr const char* name = "real::foo"; };
}
#define real_foo_ 314
struct my_foo final { static constexpr const char* name = "my_foo"; };
namespace real
{
#if !real_foo_
using foo = my_foo;
#endif
}
也就是说,real::foo
如果存在,则应将其添加到“real
”foo
,否则将使用my_foo
;后续代码使用real::foo
w/o,而不知道或关心它是实际版本还是替换版本
实现同样的目标似乎是正确的想法:
#include <type_traits>
namespace real
{
struct bar final { static constexpr const char* name = "real::bar"; };
}
struct my_bar final { static constexpr const char* name = "my_bar"; };
// https://devblogs.microsoft.com/oldnewthing/20190710-00/?p=102678
template<typename, typename = void>
constexpr bool is_type_complete_v = false;
template<typename T>
constexpr bool is_type_complete_v<T, std::void_t<decltype(sizeof(T))>> = true;
namespace real { struct bar; }
namespace real
{
using bar = std::conditional_t<is_type_complete_v<real::bar>, real::bar, my_bar>;
}
错误C2371:'real::bar':重新定义;不同的基本类型消息:请参见“real::bar”的声明
错误C2079:“bar”使用未定义的结构“real::bar” 有没有一种方法可以使
real::bar
像real::foo
一样工作,而不依赖于功能测试宏?请注意,与real::foo
一样,real::bar
的名称不能更改(例如,改为real::real\u bar
)
(实际使用案例:C++14/C++17/C++20在C++11中实现的库功能;一旦使用
std::filesystem::path
的客户机代码编写完成,它就不必更改了。)编译器抱怨您的代码,因为您试图创建两个同名实体。考虑改变
namespace real
{
struct bar final { static constexpr const char* name = "real::bar"; };
}
差不多
namespace real
{
struct absolutely_bar final { static constexpr const char* name = "real::bar"; };
}
...
namespace real { struct absolutely_bar; }
namespace real
{
using bar = std::conditional_t<is_type_complete_v<real::absolutely_bar>, real::absolutely_bar, my_bar>;
}
名称空间实数
{
struct\u bar final{static constexpr const char*name=“real::bar”;};
}
...
命名空间实{struct\u bar;}
命名空间实数
{
使用bar=std::conditional\u t;
}
PS:创建这样的别名通常是一种不好的模式,因为它并不明显。在代码中检查
currentVersion=>C++17
有什么不对?宏的用法不好。但有些是正确的(我认为分支从预处理器一个正确的)。预处理器指令的替代方法可能是使用工具链来选择要从生成中包括/排除的文件,从某个模板生成某个文件(“real.h.in”
)。
namespace real
{
struct bar final { static constexpr const char* name = "real::bar"; };
}
namespace real
{
struct absolutely_bar final { static constexpr const char* name = "real::bar"; };
}
...
namespace real { struct absolutely_bar; }
namespace real
{
using bar = std::conditional_t<is_type_complete_v<real::absolutely_bar>, real::absolutely_bar, my_bar>;
}