回答完这个问题后,我试图is_complete在Boost库中找到模板,我意识到Boost.TypeTraits中没有这样的模板.为什么Boost库中没有这样的模板?应该怎么样?
//! Check whether type complete
template<typename T>
struct is_complete
{
static const bool value = ( sizeof(T) > 0 );
};
...
// so I could use it in such a way
BOOST_STATIC_ASSERT( boost::is_complete<T>::value );
Run Code Online (Sandbox Code Playgroud)
上面的代码不正确,因为应用于sizeof不完整类型是非法的.什么是好的解决方案?在某种程度上可以在这种情况下应用SFINAE吗?
这段代码肯定是格式错误的,因为它Foo是在实例化点之后专门化的:
template <typename T>
struct Foo {
int a;
};
Foo<int> x = { 42 };
template <>
struct Foo<int> {
const char *a;
};
Foo<int> x = { "bar" };
Run Code Online (Sandbox Code Playgroud)
由于我强调的标准部分,它形成不良:
函数模板,成员函数模板或类模板的成员函数或静态数据成员的特化可以在翻译单元内具有多个实例化点,并且除了上述实例化的点之外,对于任何这样的实例化.在翻译单元内具有实例化点的专门化,翻译单元的末尾也被认为是实例化的点.类模板的专门化在翻译单元中最多只有一个实例化点.任何模板的特化可以在多个翻译单元中具有实例化点.如果两个不同的实例化点根据单定义规则给出模板特化的不同含义,则程序形成错误,不需要诊断.
现在,这个代码是不正确的吗?
struct A;
template <typename> class Foo { };
Foo<A> foo; // note A is incomplete here
struct A {};
Run Code Online (Sandbox Code Playgroud)
如果这样Foo宣布,那么不良形象会改变吗?
struct A;
template <typename T>
struct Foo {
Foo() {
new T;
}
};
Foo<A> foo; // …Run Code Online (Sandbox Code Playgroud) 标题中的问题很清楚.更具体地说,请考虑以下示例:
#include <type_traits>
template <typename T>
struct is_complete_helper {
template <typename U>
static auto test(U*) -> std::integral_constant<bool, sizeof(U) == sizeof(U)>;
static auto test(...) -> std::false_type;
using type = decltype(test((T*)0));
};
template <typename T>
struct is_complete : is_complete_helper<T>::type {};
// The above is an implementation of is_complete from https://stackoverflow.com/a/21121104/5376789
template<class T> class X;
static_assert(!is_complete<X<char>>::type{});
// X<char> should be implicitly instantiated here, an incomplete type
template<class T> class X {};
static_assert(!is_complete<X<char>>::type{}); // #1
X<char> ch; // #2
Run Code Online (Sandbox Code Playgroud)
此代码与GCC和Clang编译.
c++ templates language-lawyer template-instantiation implicit-instantiation
我尝试检测一个类是否已在 C++ 中实现。该类要么仅在之前声明过(情况 1),要么已实现(情况 2)。为了检测类的实现,SFINAE 表达式应该评估sizeof(T)模板参数,如果类不完整,则模板参数将失败。
#include <type_traits>
// 1. Feature not supported: Class only declared
class Test;
// 2. Feature supported: Class implemented
// class Test {};
// Detection if class is complete
template<class T, class Enable = void>
struct is_complete
{
static constexpr bool value = false;
};
template<class T>
struct is_complete<T, std::enable_if_t<(sizeof(T) == sizeof(T))>>
{
static constexpr bool value = true;
};
int main(void)
{
if constexpr (is_complete<Test>::value)
{
// static_assert(is_complete<Test>::value, "Test is not complete"); …Run Code Online (Sandbox Code Playgroud) 我想编写一个 C++ 函数来检查其模板参数类是否不完整,因此只有类声明可用,但没有所有类成员的完整定义。
我的函数incomplete()与一些演示程序如下所示:
#include <type_traits>
#include <iostream>
template <typename T, typename V = void> constexpr bool is_incomplete = true;
template <typename T> constexpr bool is_incomplete<T, std::enable_if_t<sizeof(T)>> = false;
template <typename T> constexpr bool incomplete() { return is_incomplete<T>; }
struct A;
void print() { std::cout << incomplete<A>(); }
struct A {}; //this line affects GCC
int main()
{
print();
}
Run Code Online (Sandbox Code Playgroud)
它在 Clang 打印中运行良好,但在 GCC 中,尽管类的功能不完整,1程序仍会打印。
https://gcc.godbolt.org/z/qWW3hqbEv0Aprint
是 GCC 错误还是我的程序有问题?