考虑以下代码:
template<typename T>
class Base
{
template<typename U>
friend void f(void *ptr) {
static_cast<Base<U>*>(ptr)->run();
}
protected:
virtual void run() = 0;
};
class A : public Base<A>
{
protected:
virtual void run() {}
};
/*
class B : public Base<B>
{
protected:
virtual void run() {}
};
*/
Run Code Online (Sandbox Code Playgroud)
现在可以编译良好(ideone)。但是,如果我取消注释的定义B,那么它将给出以下错误(ideone):
prog.cpp: In instantiation of ‘Base<B>’:
prog.cpp:20: instantiated from here
prog.cpp:6: error: redefinition of ‘template<class U> void f(void*)’
prog.cpp:6: error: ‘template<class U> void f(void*)’ previously defined …Run Code Online (Sandbox Code Playgroud) 有两个模板类A和B.如何强制它们被实例化为相同类型而不与另一个嵌套?例如,如果我定义这两个类如下:
template <class T>
class A {};
template <class T>
class B {};
Run Code Online (Sandbox Code Playgroud)
那么有可能的是,用户可以做这样的事A<int> a;,并B<float> b;
我想强制A和B具有完全相同的类型,但我不希望它们彼此嵌套.所以当有人使用这两个类时,A和B必须具有相同的类型.有没有办法做到这一点?那些像这样设计课程的好习惯是什么?
谢谢
我正在为分数创建模板类,分子和分母的类型可以是int,float或double。当重载算术或关系运算符时,当我尝试添加两个类(例如A类和B类)时,它会给出错误
在头文件“ fraction.h”中
#include<iostream>
using namespace std;
template <class T>
class fraction
{
friend ostream& operator<< <T>(ostream&, const fraction<T>&);
public:
fraction();
fraction<T>(T, T);
friend fraction<T> operator+(const fraction<T>&, const fraction<T>&);
private:
T numerator;
T denominator;
};
template <class T>
fraction<T>::fraction()
{
numerator = 0;
denominator = 1;
}
template <class T>
fraction<T>::fraction(T num, T denom)
{
numerator = num;
denominator = denom;
}
template <class T>
ostream& operator<<(ostream& osObject, const fraction<T>& frac)
{
osObject << frac.numerator << "/" << frac.denominator;
return …Run Code Online (Sandbox Code Playgroud) 在下面的示例中,我们使用C ++ 17功能“类模板参数推导”来推断val类型为Base<int, double, bool>:
template<class T, class U, class V>
struct Base {
Base(T, U) { };
Base(T, U, V) { };
Base(V) { };
};
void func() {
Base val(1, 4., false);
}
Run Code Online (Sandbox Code Playgroud)
现在,是否可以部分指定模板参数,然后推导出其余参数?实际上是这样的:
Base<V = bool> val1(1, 4.); // U & V deduced --> Base<int, double, bool>
Base<T = bool, T = int> val2(5.); // V deduced --> Base<bool, int, double>
Run Code Online (Sandbox Code Playgroud)
我试过了
template<class T, class U> using Base2 = Base<T, U, …Run Code Online (Sandbox Code Playgroud) 我尝试使用 gcc 10 构建以下内容-std=gnu++20 -fconcepts:
template <std::signed_integral T>\nclass MyClass{ T a; };\n\ntemplate <std::unsigned_integral T>\nclass MyClass{ T a; };\nRun Code Online (Sandbox Code Playgroud)\n\n为什么这段代码会导致以下错误?
\n\n> declaration of template parameter \xe2\x80\x98class T\xe2\x80\x99 with different constraints\n> 55 | template <std::unsigned_integral T>\n> | ^~~\nRun Code Online (Sandbox Code Playgroud)\n\n应该没问题吧?
\ntemplate-specialization class-template c++-concepts c++20 gcc10
我想创建一个静态类,它将充当固定大小的内存分配器。
让我们看一下这个简化的例子:
struct A {};
struct B {};
template<class T, std::size_t MaxNumObjects>
class InternalContainer
{
public:
static constexpr std::size_t maxObjects = MaxNumObjects;
static T* createObject()
{
return ::new(&objects[idx++]) T;
}
static T* releaseObject() { /*...*/ };
private:
using buffer_t = std::aligned_storage_t<sizeof(T), alignof(T)>;
static buffer_t objects[maxObjects];
static std::size_t idx;
};
A* a = InternalContainer<A, 2>::createObject();
B* b = InternalContainer<B, 5>::createObject();
Run Code Online (Sandbox Code Playgroud)
如何根据类型预定义容器的最大尺寸?
// will be replaced "InternalContainer<A, 2>"
A* a = MyContainer<A>::createObject();
// will be replaced "InternalContainer<B, 5>"
B* b = MyContainer<B>::createObject(); …Run Code Online (Sandbox Code Playgroud) 我有一个类模板:
template< typename ...bounded_types >
struct variant {};
Run Code Online (Sandbox Code Playgroud)
但是想禁止有界类型的空列表,即variant<>必须在编译时禁止.我可以做以下事情:
template<>
struct variant<>;
Run Code Online (Sandbox Code Playgroud)
但它不太清楚:如果我的变体库包含大量标题,那么它是不明显的,上面的特化是否不是类的前向声明,定义在下面的某处.在我看来,理想的想象解决方案将是:
template<>
struct variant<> = delete;
Run Code Online (Sandbox Code Playgroud)
这在很大程度上是明确的,但遗憾的是,C++语法禁止这样做.
什么是满足所述意图的最明确的方式?
我有一个链表,其中包含指向第一个和最后一个节点的指针以及指示列表中有多少个节点的大小。\n我有一个返回第一个节点的函数。
\n我希望能够使用 更改第一个节点中的 m_data queue1.front() = 3;。然而,我得到
invalid conversion from \xe2\x80\x98int\xe2\x80\x99 to \xe2\x80\x98Node<int>*\xe2\x80\x99\nRun Code Online (Sandbox Code Playgroud)\n编译时出错
\ninvalid conversion from \xe2\x80\x98int\xe2\x80\x99 to \xe2\x80\x98Node<int>*\xe2\x80\x99\nRun Code Online (Sandbox Code Playgroud)\ntemplate <class T>\nclass Node {\npublic:\n Node(const T& t);\n ~Node() = default; // Destructor\n Node(const Node&) = default; // Copy Constructor set to default\n Node& operator=(const Node&) =\n default; // Assignment operator set to default\n T& getData();\n const T& getData() const;\n Node* getNext();\n void setNext(Node<T>* newNext);\n\nprivate:\n T m_data;\n Node* m_nextNode;\n};\n\ntemplate <class T>\nNode<T>::Node(const T& t) {\n …Run Code Online (Sandbox Code Playgroud) 我有一个链表,其中包含指向第一个和最后一个节点的指针以及指示列表中有多少个节点的大小。\n我已经为指向节点地址的队列实现了迭代器,我已经成功了实现 begin()、end() 和 ==、!=,并进行了测试,\n但我无法为迭代器实现 ++() 和 ++(int) 运算符,我希望 ++ 运算符更改节点到链表中下一个节点的地址,当我尝试编译时出现以下错误:no matching function for call to \xe2\x80\x98Node<int>::getNext() const\xe2\x80\x99\n以及如何使迭代器运算符重载工作而无需typename在声明开头键入
Node班级:
template<class T>\nclass Node {\n public:\n Node(const T& t);\n ~Node()=default; // Destructor\n Node(const Node&) = default; // Copy Constructor set to default\n Node& operator=(const Node&) = default; // Assignment operator set to default\n T& getData();\n const T& getData() const;\n Node* getNext();\n void setNext(Node<T>* newNext);\n private:\n T m_data;\n Node* m_nextNode;\n};\n\ntemplate<class T>\nNode<T>::Node(const T& t) {\n this->m_data=t;\n this->m_nextNode=nullptr;\n}\n\ntemplate<class T>\nNode<T>* …Run Code Online (Sandbox Code Playgroud) 考虑以下场景:
template <
typename T,
bool B = std::is_default_constructible_v<T>>
class toy_example;
template<typename T>
class toy_example<T, true>
{
public:
toy_example() = default; // e.g. for default constructible types
toy_example(const T& value);
public:
void monomorphic(T);
private:
T m_value;
};
template<typename T>
class toy_example<T, false>
{
public:
toy_example() = delete; // e.g. for non-default constructible types
toy_example(const T& value); // Repeated declaration
public:
void monomorphic(T); // Repeated declaration
private:
T m_value;
};
// Implementation
template<typename T>
toy_example<T, true>::toy_example(const T& value) : m_value(value) {} …Run Code Online (Sandbox Code Playgroud) class-template ×10
c++ ×9
templates ×6
c++17 ×4
c++11 ×3
class ×2
c++-concepts ×1
c++20 ×1
friend ×1
gcc10 ×1
sfinae ×1