noob在这里仍在试验模板.试图编写一个消息处理类模板
template <typename T> class MessageProcessor {
//constructor, destructor defined
//Code using t_ and other functions
foo( void ) {
//More code in a perfectly fine method
}
private: T *t_
};
Run Code Online (Sandbox Code Playgroud)
全部在头文件中定义.我已经建立并测试了我的课程,一切都很好.现在,我正在尝试这样做:
template <typename T> class MessageProcesor {
//Same stuff as before
foo(void) {
//Same code as before in foo, but one new line:
t_->getMessageSender<MessageType>();
}
private: T *t_;
};
Run Code Online (Sandbox Code Playgroud)
但是,这行在">"标记之前给出了错误表达式类型的错误.
我添加了必要的头文件来定义MessageType是什么.我之前很久就使用过这个函数,只是不是在这种情况下.
我怀疑编译器不喜欢模板函数在未定义的类模板(unspecialized?)中完全定义(专用?)的事实.我并不完全了解模板"专业化"的原因.大多数解释都集中在"完整"或"部分"的概念上,而不是首先使它成为专业的概念.
如果您想查看更多代码,请道歉.我在工作时没有互联网接入,这就是我正在做的事情,所以我必须将所有内容放入我的心理"暂存器"并将其带回家.
我的一些基类获得了大量的参数.现在我想指定要使用的静态函数:
template <typename... Types>
struct SBase {
static void func() {
}
};
struct A : public SBase<int> {
};
struct B : public A, public SBase<int, double, short,
unsigned int, float, unsigned char, long, unsigned long> {
// using SBase::func; // Not possible.
// Horrible, but works.
using SBase<int, double, short,
unsigned int, float, unsigned char, long, unsigned long>::func;
};
Run Code Online (Sandbox Code Playgroud)
您可以看到,我需要两次编写模板参数,这会导致代码重复.
有没有办法摆脱它?
是否可以像在C++中一样在PHP中创建类模板?PHP可能没有类似的语言结构(如C++中的关键字),但也许有一些巧妙的技巧来实现类似的功能?template
我有一个Point类想要转换为模板。在类中,我使用类型参数,因此,对于每个类,我想传递给 Point 方法,我必须使用适当类型的参数创建 Point 类的新副本。
这是C++ 的示例形式:
#include<iostream>
template <typename T>
class Point
{
public:
T x, y;
Point(T argX, T argY)
{
x = argX;
y = argY;
}
};
int main() {
Point<int> objA(1, 2);
std::cout << objA.x << ":" << objA.y << std::endl;
Point<unsigned> objB(3, 4);
std::cout << objB.x << ":" << objB.y << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在 PHP 中也是如此,但它根本不起作用(当然最后一行返回错误):
class SomeClass
{ …Run Code Online (Sandbox Code Playgroud) 好的,这是一个复杂的问题.
我有一个多次实例化的C++类模板.对于这些实例中的每一个,我都需要执行一个注册一些运算符的函数.这需要该模板实例中使用的第一目标(这并不意味着它必须在执行前每个模板实例只需进行一次在 instanciation这在编译时有发生).
最新的我手动完成了这个.但这是一种痛苦.所以我想自动执行注册功能.
我目前的想法是在构造函数中调用一个受保护的注册方法.然而,每当构造一个类的实例时,这需要(小的)开销.由于这种情况经常发生,我想避免这种开销.
我还尝试使用静态RAII帮助程序成员,但如果没有主动访问静态模板类成员,则不会构造静态模板类成员,因此尝试失败.
有没有办法在类模板instanciation上执行代码(通过函数或可能由RAII帮助程序类)而没有运行时开销?
假设我有以下文件:
Generic.h:复杂的模板类
#pragma once
template<typename K, typename V, template<typename Key, typename Value, typename ...> typename C>
struct GenericMap
{
C<K, V> key;
};
Run Code Online (Sandbox Code Playgroud)
Special.h:定义所提及模板类的完全专用版本,从而简化易用性。
#pragma once
#include "Generic.h"
#include <string>
#include <map>
typedef GenericMap<std::string, int, std::map> SpecialMap;
Run Code Online (Sandbox Code Playgroud)
Client.h:使用SpecialMap并定义前向声明的客户端。
#pragma once
class SpecialMap; // Wrong forward declaration
struct Client {
Client();
SpecialMap* map;
};
Run Code Online (Sandbox Code Playgroud)
Client.cpp:客户代码可能知道Generic.h和Special.h
#include "Client.h"
#include "Special.h"
Client::Client()
{
map["343"] = 2;
}
Run Code Online (Sandbox Code Playgroud)
main.cpp:
#include <Client.h>
int main(int argc, char**args) …Run Code Online (Sandbox Code Playgroud) 考虑这个代码:
template <typename T>
class Singleton
{
};
class Logger : public Singleton<Logger> {
friend class Singleton;
};
Run Code Online (Sandbox Code Playgroud)
它在 gcc 和 clang 中编译,但它有效吗?[temp.local].1 说:
当它与模板参数列表一起使用时,作为模板模板参数的模板参数,或作为朋友类模板声明的详细类型说明符中的最终标识符,它是一个模板名称指的是类模板本身。
粗体部分似乎适用,并且朋友声明似乎需要类型名称而不是模板名称(参见 [class.friend])。
编译器错了还是我误读了标准?
c++ friend-class language-lawyer class-template injected-class-name
我有一个继承基类模板的构造函数的类模板。(对于c++20)有没有办法从基类的构造函数参数推导出派生类的模板参数?
如果我明确指定类型,那就有效。或者,如果我重新实现构造函数并调用基类的构造函数,这也可以工作,但是有没有办法做到这一点?
template<typename T>
struct CTestBase
{
using Type = T;
CTestBase() = default;
CTestBase(T t){}
};
template<typename T>
struct CTestDer : public CTestBase<T>
{
using CTestBase<T>::CTestBase;
};
void test()
{
//CTestDer der(int{}); //ERROR
CTestDer<int> der(int{}); //OK
}
Run Code Online (Sandbox Code Playgroud) 考虑以下示例:
template <typename T>
class A
{
public:
void foo () const {t->foo();}
virtual void fooVirtual() {t->foo();} // MSVC: use of undefined type 'B'
protected:
T* t;
};
class B; // only forward declared
const A<B>& get(); // will be defined in another translation unit
void foo(const A<B>& a); // will be defined in another translation unit
int main ()
{
const A<B>& a = get();
foo(a); // MSVC: class template instantiation 'A<B>' being compiled
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这会在 CLang …
以下两个片段有什么区别?
<T>for 运算符 <<template<typename T>
class Stack {
...
friend std::ostream& operator<< <T> (std::ostream&,
Stack<T> const&);
};
Run Code Online (Sandbox Code Playgroud)
<T>template<typename T>
class Stack {
...
friend std::ostream& operator<< (std::ostream&,
Stack<T> const&);
};
Run Code Online (Sandbox Code Playgroud) 当我注意到一种这样的情况(如下所示)在 clang 和 msvc 中编译良好但在 gcc 中编译失败时,我试图显式地专门化一个成员函数模板。这是验证相同内容的链接:https ://godbolt.org/z/15z4nT5Kx
struct C
{
template<typename T>
void f()
{
}
template<> void f<int>()
{
}
};
int main()
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
从上面的链接中可以看出,clang 和 msvc 编译程序没有任何问题,但 gcc 说:
<source>:10:14: error: explicit specialization in non-namespace scope 'struct C'
10 | template<> void f<int>()
| ^
<source>:10:21: error: template-id 'f<int>' in declaration of primary template
10 | template<> void f<int>()
| ^~~~~~
Run Code Online (Sandbox Code Playgroud)
这里是哪个编译器?