具有无效成员函数的模板类
Template class with invalid member functions
在c++中实例化类模板的类不能与其某些成员函数一起工作是合法的吗?
例如:class A {
public:
void f() { }
};
class B {
};
template<typename T>
class Wrapper {
private:
T t_;
public:
void call_f() { t_.f(); }
};
int main() {
Wrapper<A> a;
Wrapper<B> b;
a.call_f();
}
这段代码可以编译,我可以使用b
,只要我不尝试调用b.call_f()
。(同样用template class Wrapper<B>;
显式实例化它会导致编译错误,因为它实例化了所有成员函数。)
这是保证工作还是它是未定义的行为?如果是这样,在c++ 17中会随着概念和需求的引入而改变吗?
一般来说是的。类模板的非虚成员函数本身就是函数模板,和所有函数模板一样,它们只有在使用时才被实例化。因此,如果您从不使用类模板特化的某些成员函数,则成员函数不必对该特化有效。
从c++ 11开始,标准库实际上充分利用了这种细粒度的实例化控制。容器的类型要求适用于成员函数,而不是整个模板,因此,例如,你可以有一个std::map<K, T>
,其中T
不是默认可构造的;你不能在它上面调用operator[]
。
请注意,显式类模板实例化将实例化所有成员函数。
这是标准行为,不会改变。
原因如下:模板是需要处理各种类型参数的泛型代码。模板化代码中的一些操作可能对一种类型完全有效(如call_f
对A
),但对另一种类型却完全错误(如call_f
对B
)。标准中做出的决定是允许无意义的模板代码,例如B
类型的call_f
,只要这个模板函数从不被使用(这会触发模板函数的编译)。
这样,代码就可以是通用的并且安全的,因为这些检查是在编译时完成的。
相关文章:
- 为什么将值返回函数传递给重载=运算符对运算符函数有效,而对其他运算符无效
- 程序中的布尔函数返回输入的范围无论如何都是无效的
- 在这个函数中是有缺陷的,因为取消引用 null 是无效的,所以我想更改代码
- 在 Microsoft Access SQL 中调用自定义 DLL 函数时传递的内存地址无效
- C++无效的函数类型转换
- C++无效使用非静态成员函数?
- 模板和无效函数调用C++
- 错误: 无效使用非静态数据成员"应用程序::应用程序构造函数"
- 无效打印(矢量<string>)函数未打印
- 在 stream_descriptor::async_wait 中无效使用非静态成员函数
- C26486 - 不向函数传递可能无效的指针?
- 为什么构造函数的虚拟函数调用有时有效,但其他调用却无效
- 调用boost v1.58中的函数时出现模板名称使用无效错误
- 使用 vector.sort() 的非静态成员函数无效使用
- 将数组传递给构造函数无效
- 使用auto参数munmap_chunk()返回auto的函数:无效指针
- Boost::函数绑定的成员函数无效
- 为什么在模板类中声明函数无效?
- 使用非英语文件名调用avio_open函数无效
- Android NDK线程使用非静态成员函数无效