出于内省的目的,有时我想自动为类型或类似的东西分配序列号.
不幸的是,模板元编程本质上是一种功能语言,因此缺乏实现这种计数器的全局变量或可修改状态.
或者是吗?
按请求的示例代码:
#include <iostream>
int const a = counter_read;
counter_inc;
counter_inc;
counter_inc;
counter_inc;
counter_inc;
int const b = counter_read;
int main() {
std::cout << a << ' ' << b << '\n'; // print "0 5"
counter_inc_t();
counter_inc_t();
counter_inc_t();
std::cout << counter_read << '\n'; // print "8"
struct {
counter_inc_t d1;
char x[ counter_read ];
counter_inc_t d2;
char y[ counter_read ];
} ls;
std::cout << sizeof ls.x << ' ' << sizeof ls.y << '\n'; // print "9 …Run Code Online (Sandbox Code Playgroud) 如果完全定义了类型,是否可以使用SFINAE进行检查?
例如
template <class T> struct hash;
template <> struct hash<int> {};
// is_defined_hash_type definition...
enum Enum { A, B, C, D };
static_assert ( is_defined_hash_type<int> ::value, "hash<int> should be defined");
static_assert (! is_defined_hash_type<Enum>::value, "hash<Enum> should not be defined");
Run Code Online (Sandbox Code Playgroud)
解决方案不应该修改哈希结构.
我想检查某个模板专业化是否存在,其中一般情况没有定义.
鉴于:
template <typename T> struct A; // general definition not defined
template <> struct A<int> {}; // specialization defined for int
Run Code Online (Sandbox Code Playgroud)
我想定义一个像这样的结构:
template <typename T>
struct IsDefined
{
static const bool value = ???; // true if A<T> exist, false if it does not
};
Run Code Online (Sandbox Code Playgroud)
有没有办法做到这一点(理想情况下没有C++ 11)?
谢谢
我有一个这样的课:
class Inner;
class Cont
{
public:
Cont();
virtual ~Cont();
private:
Inner* m_inner;
};
Run Code Online (Sandbox Code Playgroud)
在.cpp中,构造函数创建了一个Innerwith new和析构函数delete的实例.这工作得很好.
现在我想更改此代码以便使用,auto_ptr所以我写道:
class Inner;
class Cont
{
public:
Cont();
virtual ~Cont();
private:
std::auto_ptr<Inner> m_inner;
};
Run Code Online (Sandbox Code Playgroud)
现在,构造函数初始化了auto_ptr,而析构函数什么都不做.
但它不起作用.当我实例化这个类时,问题似乎就出现了.我收到这个警告:
警告C4150:删除指向不完整类型'Inner'的指针; 没有破坏者叫
好吧,这显然非常糟糕,我明白为什么会发生这种情况,编译器不知道Inner实例化模板的时候auto_ptr<Inner>
所以我的问题:是否有一种方法可以使用auto_ptr前向声明,就像我在仅使用普通指针的版本中所做的那样?我
必须向#include每个班级宣布一个指针是一个巨大的麻烦,有时候,这是不可能的.这个问题通常是如何处理的?
如何允许在以下代码中使用私有析构函数删除对象?我已将实际程序缩减为以下示例,但它仍然可以编译并运行.
class SomeClass;
int main(int argc, char *argv[])
{
SomeClass* boo = 0; // in real program it will be valid pointer
delete boo; // how it can work?
return -1;
}
class SomeClass
{
private:
~SomeClass() {}; // ! private destructor !
};
Run Code Online (Sandbox Code Playgroud) 有没有办法在标题中的那个点上使用static_assert类型T 不完整?如果有人在他们不应该的地方添加#includes,那么这个想法就会产生编译错误.
使用该链接的答案,
namespace
{
template<class T, int discriminator>
struct is_complete {
static T & getT();
static char (& pass(T))[2];
static char pass(...);
static const bool value = sizeof(pass(getT()))==2;
};
}
#define IS_COMPLETE(X) is_complete<X,__COUNTER__>::value
class GType;
static_assert(!IS_COMPLETE(GType),"no cheating!");
Run Code Online (Sandbox Code Playgroud)
不幸的是,这给出了"无效使用incomlete类型"错误,哦.有没有办法断言否定?
我想实现像sizeof(complete_type)这样的行为将返回实际sizeof,而sizeof(incomplete_type) - 将只是0
我需要这个为IPC(进程间)通信提供扩展的运行时类型信息,每种类型的描述结构:
struct my_type_info
{
bool is_pointer;
size_t size; //for double* will be 4 on i386. that is sizeof(double*)
size_t base_size; //for double* will be 8. that is sizeof(double)
};
Run Code Online (Sandbox Code Playgroud)
进入我的系统时出现类似MyOnlyDeclaredClass类的问题; 我有编译错误,显然是因为我无法控制它的大小.
boost type_traits http://www.boost.org/doc/libs/1_48_0/libs/type_traits/doc/html/index.html建议了许多编译时类,但没有'is_incomplete'
有趣的编译器是VS2008,VS2010,clang 3,gcc-4.6,gcc-4.7
结构化绑定功能表示,如果tuple_size模板是完整类型,它会像分解一样使用元组.如果std::tuple_size在程序中的某一点是给定类型的完整类型并且在另一点未完成,会发生什么?
#include <iostream>
#include <tuple>
using std::cout;
using std::endl;
class Something {
public:
template <std::size_t Index>
auto get() {
cout << "Using member get" << endl;
return std::get<Index>(this->a);
}
std::tuple<int> a{1};
};
namespace {
auto something = Something{};
}
void foo() {
auto& [one] = something;
std::get<0>(one)++;
cout << std::get<0>(one) << endl;
}
namespace std {
template <>
class tuple_size<Something> : public std::integral_constant<std::size_t, 1> {};
template <>
class tuple_element<0, Something> {
public:
using type = int; …Run Code Online (Sandbox Code Playgroud) c++ one-definition-rule undefined-behavior c++17 structured-bindings
当定义某种类型时,我想选择一个模板的特殊化。
我仍然无法绕开SFINAE :(.。我可能已经接近或者可能已经完全离开了。我尝试了不同的方法,这是某种方法,我至少希望了解为什么它不起作用(is_complete基本上是从这里被盗):
#include <iostream>
#include <type_traits>
template <typename T, class = void>
struct is_complete : std::false_type {};
template <typename T>
struct is_complete<T,decltype(void(sizeof(T)))> : std::true_type {};
// this should be called if foo is not defined
void test() { std::cout << "test base\n"; }
// forward declare foo
struct foo;
// this should be called if foo is defined
template <typename T>
std::enable_if<is_complete<foo>::value,void> test() {
foo::bar();
}
// this is either defined or not
struct foo{ …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 错误还是我的程序有问题?
我希望下面的NDR形成不良,但似乎不是:-(
#include <type_traits>
template <typename T, typename Enabler = void>
struct is_complete : std::false_type {};
template <typename T>
struct is_complete<T, std::void_t<decltype(sizeof(T) != 0)>> : std::true_type {};
class X;
static_assert(!is_complete<X>::type{}); // incomplete type
class X {};
static_assert(!is_complete<X>::type{}); // complete, but already instantiated
Run Code Online (Sandbox Code Playgroud)
注意:假设sizeof(T) != 0对完整性特征有效(因为没有类型可以使用sizeof(T) == 0,使用其他常量会强制为特征找到更好的名称:-))
如果已经隐式实例化了隐式实例化的特殊化,它是代码的变体吗?,程序已被宣布为格式错误的程序,无需诊断(NDR),因为该方法 is_complete_helper<X>::test<X> 具有2种不同的含义,具体取决于实例化点.
似乎附近的参考文件使程序形成不良,但并不像我所理解的那样:
在假设实例中对这种构造的解释不同于在模板的任何实际实例化中对相应构造的解释.
函数模板,成员函数模板或类模板的成员函数或静态数据成员的特化可以在翻译单元内具有多个实例化点,并且除了上述实例化的点之外,对于任何这样的实例化.在翻译单元内具有实例化点的专门化,翻译单元的末尾也被认为是实例化的点.类模板的专门化在翻译单元中最多只有一个实例化点.任何模板的特化可以在多个翻译单元中具有实例化点.如果两个不同的实例化点根据单定义规则给出模板特化的不同含义,则程序形成错误,不需要诊断.
我错了 ?或者不幸的是这个程序是正确的.
c++ ×11
templates ×6
sfinae ×4
c++11 ×2
auto-ptr ×1
c++17 ×1
pointers ×1
shared-ptr ×1
state ×1