我无法理解非类型模板参数,并希望有人可以阐明这一点。
#include <iostream>
template<typename T, int a>
void f() {
if (a == 1) {
std::cout << "Hello\n";
} else {
T("hello");
}
}
int main() {
f<int, 1>;
}
当我编译它时,我收到一个错误说:
/tmp/conditional_templates.cc:13:12: required from here
/tmp/conditional_templates.cc:8:5: error: cast from ‘const char*’ to ‘int’ loses precision [-fpermissive]
T("hello");
^
但是,编译器不能检测到非类型参数“a”为1,因此不会采用else分支吗?或者说这太过于期待了?在这种情况下,我该如何完成这样的事情?
答案 0 :(得分:3)
我必须承认,老实说,我没有看到这样做的根本原因,而是你的代码。除了明显的错误(无法为main()
中的函数调用提供parens,以及警告(将char地址转换为int
的数据丢失),关于条件包含的更大问题很重要。< / p>
如果您有以下代码:
if (something)
{
do something
}
显然必须编译,并且不有条件地这样做。 something
源自非类型模板参数没有任何区别。您需要从函数内的if-expression中获取逻辑,而不是从模板扩展控制机制中获取逻辑。专业化是一种这样的技术,SFINAE是另一种技术:
#include <iostream>
#include <iomanip>
#include <type_traits>
#include <cstdint>
static const char* something = "something";
template<class T, bool a>
typename std::enable_if<a>::type f()
{
std::cout << __PRETTY_FUNCTION__ << '\n';
std::cout << something << '\n';
}
template<class T, bool a>
typename std::enable_if<!a>::type f()
{
std::cout << __PRETTY_FUNCTION__ << '\n';
std::cout << std::hex << T(something) << '\n';
}
int main()
{
f<int, true>();
f<intptr_t, false>();
}
<强>输出强>
typename std::enable_if<a>::type f() [T = int, a = true]
something
typename std::enable_if<!a>::type f() [T = long, a = false]
100001f18
你在每个人身上所做的都取决于你。当然,你可以使用预处理器宏进行大量/全部操作,但那里的乐趣在哪里?
答案 1 :(得分:1)
Try this instead:
#include <iostream>
template<typename T, int a>
struct A {
void f() {
T("hello");
}
};
template<typename T>
struct A<T,1> {
void f() {
std::cout << "Hello\n";
}
};
int main() {
A<int,1> a;
a.f();
A<int,2> b;
b.f();
}
Now, this uses partial template specialization in order to provide alternative implementations for specific values of the template parameters.
Note that I've used a class, because function templates cannot be partially specialized
答案 2 :(得分:0)
Seems that in your environment sizeof(int)
is different than sizeof(const char*)
.
In such case part of code: T("hello")
which is in fact int("hello")
tries to convert const char*
to int
. Compiler is complaining because precision would be lost in such a conversion.
To check the sizes of int
and const char*
:
std::cout << sizeof(int) << std::endl;
std::cout << sizeof(const char*) << std::endl;
else
branch won't be run when calling f<int, 1>()
but it does not mean that compiler will ignore errors within else
code.