确保C 模板不会与缺少功能进行编译
Ensuring C++ template does not compile with missing functions
我有一个模板类template<typename T> Foo
使用T
的某些功能。但是,事实证明,即使没有T
具有所有必要的成员功能,代码也可以编译。一个例子如下。
template<class T>
struct Foo {
T t;
int foo() {
return t.foo();
}
int bar() {
return t.bar();
}
};
struct baz {
int foo() {
return 42;
}
};
int main() {
Foo<baz> x;
return x.foo();
}
如果T
不提供所有必要的功能,我该如何确保代码不编译?我知道,如果我使用包含所有继承并从中得出的基类,则可以做到这一点。但是,如果可以使用模板没有太多其他代码,我将非常感谢。
我在Linux上使用GCC 4.8.2。
为了要求类型是具有某些可访问成员功能的类类型,只需参考它们即可。例如。在Foo
的每个构造函数中,您可以说
Foo()
{
(void) sizeof( decltype( t.foo() ) );
(void) sizeof( decltype( t.bar() ) );
}
上面的示例比示例所需的要多一些,但是显示了如何轻松确保具有某些参数或具有某些签名的功能。
。或者您可以将这些表达式放在static_assert
中。
类似于@cheers的答案,但是有点通用(即使Foo
不包含T
):
template<typename...>
struct test {};
template<typename T>
using Foo_test = test<
decltype(std::declval<T>().foo()),
decltype(std::declval<T>().bar())
>;
template<class T>
struct Foo : Foo_test<T> {
// ...
};
此问题与目前为C 14设计的概念有关,因此将来可能会更方便。
使用您的代码,我只需使用static_assert
和std::is_member_function_pointer
如下(在此处文档)
template<class T>
struct Foo {
static_assert(std::is_member_function_pointer<decltype(&T::foo)>::value, "");
static_assert(std::is_member_function_pointer<decltype(&T::bar)>::value, "");
T t;
int foo() {
return t.foo();
}
int bar() {
return t.bar();
}
};
struct baz {
int foo() {
return 42;
}
};
int main() {
Foo<baz> x;
return x.foo();
}
相关文章:
- 如何获得CMake Tools以在Visual Studio Code中编译具有C++11(或更高版本)功能的程序?
- C++11 功能 std::map::at 编译旧版本的C++
- 如何在cmake工具链文件中设置编译功能,以便已知的自定义编译器使用target_compile_features
- 如何在专门使用交换功能时修复 gcc8 的编译错误/
- 不同C++功能的编译时间
- 自定义 {fmt} 格式化函数,具有编译时格式字符串检查功能
- 错误错误:无法编译内置功能
- 如何实现声明功能-C 11,编译时间
- 指向功能编译错误的指针
- 在C 程序中编译C 功能
- 编译时未检测到主要功能
- 是否有任何挂钩接口在编译时间内更换功能
- 编译后如何计算某些二进制功能(或基本块)的校验和
- 如果功能超载,则BOOST PHOENIX成员功能操作员无法编译
- 在编译时检查课堂中是否可以使用静态功能
- 使用SFINAE检测编译时间是否存在过载的独立式功能
- 在Linux Mint上编译Qt-OpenGL功能测试失败
- 尝试调用功能指针到成员函数时会出现编译错误
- 如果将功能的非常简单的定义移动到.cpp,则编译时间的减少是多少
- 如果我使用c++11功能编译一个文件,同时将其链接到一个没有c++11编译器选项编译的库,会有什么问题吗