后续问题是[是否转换为指向模板的指针实例化该模板?].
问题就像标题所说的那样,问题的其余部分是类模板的约束和用法示例,以及我尝试实现目标.
一个重要的约束:用户通过继承我的类模板来实例化模板(而不是通过显式实例化它,如下面的尝试).因此,对我来说很重要的是,如果可能的话,用户不需要做任何额外的工作.只是子类化它应该工作(子类实际上在一个字典中注册自己,而不是用户除了用CRTP子类化一个额外的类模板之外的任何事情,子类永远不会被创建它的用户直接使用).我愿意接受用户需要做额外工作的答案(如从额外的基础派生),如果真的没有别的办法.
一个代码片段,用于解释如何使用类模板:
// the class template in question
template<class Resource>
struct loader
{
typedef Resource res_type;
virtual res_type load(std::string const& path) const = 0;
virtual void unload(res_type const& res) const = 0;
};
template<class Resource, class Derived>
struct implement_loader
: loader<Resource>
, auto_register_in_dict<Derived>
{
};
template<class Resource>
Resource load(std::string const& path){
// error should be triggered here
check_loader_instantiated_with<Resource>();
// search through resource cache
// ...
// if not yet loaded, load from disk
// loader_dict is …Run Code Online (Sandbox Code Playgroud) 下面的代码无法在gcc 7.3.0和clang 6.0.0上编译(但似乎在MSVC下编译正常):
#include <utility>
struct IncompleteType;
template<typename T>
struct Container {
T value;
};
using Uninstantiatable = Container<IncompleteType>;
auto foo() -> decltype(static_cast<Uninstantiatable const&>(std::declval<Uninstantiatable const&>())) {
throw 1;
}
Run Code Online (Sandbox Code Playgroud)
我得到的错误是这样的:
<source>:7:7: error: field has incomplete type 'IncompleteType'
T value;
^
<source>:12:24: note: in instantiation of template class 'Container<IncompleteType>' requested here
auto foo() -> decltype(static_cast<Uninstantiatable const&>(std::declval<Uninstantiatable const&>())) {
^
<source>:3:8: note: forward declaration of 'IncompleteType'
struct IncompleteType;
^
1 error generated.
Compiler returned: 1
Run Code Online (Sandbox Code Playgroud)
亲自尝试一下:https://godbolt.org/g/5AW37K
但是,如果我替换第10行,它就会编译
using Uninstantiatable …Run Code Online (Sandbox Code Playgroud) 为什么在+使用运算符语法调用一元时会收到错误消息?如果我用函数语法调用它,就可以了。现场演示。
template <int size>
struct Buffer { char buf[size]; };
template <class T>
struct Wrapper { void operator+() {} };
Wrapper<Buffer<-5>> a;
void f1() { +a; } // error: Buffer<-5>::buf has negative size
void f2() { a.operator+(); } // OK
Run Code Online (Sandbox Code Playgroud)