【发布时间】:2017-09-20 12:37:34
【问题描述】:
我正在尝试创建一个模板化函数,它在编译时强制使用只使用特化。我引用了Force a compile time error in a template specialization,它建议在继承自std::false_type 的东西上使用static_assert。
#include <iostream>
using namespace std;
template<typename T>
struct always_false : std::false_type {};
//Case: Default
template<typename T>
void foo(T val) {
static_assert(always_false<T>::value, "");
}
//Case: bool
template<>
void foo<bool>(bool val) {
cout << "Is explicitly a bool! " << val << endl;
}
//Case: int
template<typename T, typename std::enable_if<!std::is_same<T,bool>::value && std::is_convertible<T,int>::value,int>::type=0>
void foo(T val) {
cout << "Can be implicitly converted to int! " << (int)val << endl;
}
int main() {
foo(true); //(Good) Works correctly
foo((int)5); //(Bad) Error: call of overload foo(int) is ambiguous
foo((unsigned int)10); //(Bad) Error: call of overload foo(unsigned int) is ambiguous
foo((void*)nullptr); //(Good) Error: static assertion failed
return 0;
}
当我传入int 或unsigned int 时,编译器抱怨该调用不明确,表明它可以使用Case: Default 或Case: int。
这很令人困惑,因为 Case: Default 有 always_false static_assert(),我希望编译器会禁止它。
我最后一个传入void* 的示例成功触发static_assert() 并导致编译时错误。
我是使用 SFINAE 模板元编程编程的新手,所以我怀疑我在 Case: int 专业化中做错了什么
两个问题:
- 为什么这段代码中的
foo(int)不明确? - 有没有更好的使用方法
获得这种期望行为的模板(显式
bool特化 + 隐式整数特化)?
【问题讨论】:
-
您不能声明模板特化,即使是对其实例化的任何类型都无效的主要特化。无需诊断。
标签: c++ c++11 templates sfinae template-specialization