I was reading about template functions and got confused by this problem:
#include <iostream>
void f(int) {
std::cout << "f(int)\n";
}
template<typename T>
void g(T val) {
std::cout << typeid(val).name() << " ";
f(val);
}
void f(double) {
std::cout << "f(double)\n";
}
template void g<double>(double);
int main() {
f(1.0); // f(double)
f(1); // f(int)
g(1.0); // d f(int), this is surprising
g(1); // i f(int)
}
Run Code Online (Sandbox Code Playgroud)
The results are the same if I don't write template void g<double>(double);.
I …
c++ dependent-name function-templates name-lookup unqualified-name
我正在玩模板专业化,我发现了一个似乎无法解决的问题; 这是我的代码:
template<int length, typename T>
void test(T* array)
{
...
test<length-1>(array);
}
template<typename T>
void test<0>(T* array)
{
return;
}
Run Code Online (Sandbox Code Playgroud)
所以我要做的就是传递模板中要处理的内容的长度.
问题是,编译这个,很好地输出:
a.cpp:83:43: error: template-id 'test<0>' in declaration of primary template
a.cpp: In function 'void test(T*) [with int length= -0x000000081, T = int]':
a.cpp:77:9: instantiated from 'void test(T*) [with int length= -0x000000080, T = int]'
a.cpp:77:9: instantiated from 'void test(T*) [with int length= -0x00000007f, T = int]'
a.cpp:77:9: [ skipping 151 instantiation contexts ]
a.cpp:77:9: instantiated from 'void test(T*) …Run Code Online (Sandbox Code Playgroud) 我想知道为什么以下代码无法编译:
struct S
{
template <typename... T>
S(T..., int);
};
S c{0, 0};
Run Code Online (Sandbox Code Playgroud)
此代码无法使用clang和GCC 4.8进行编译.这是clang的错误:
test.cpp:7:3: error: no matching constructor for initialization of 'S'
S c{0, 0};
^~~~~~~
test.cpp:4:5: note: candidate constructor not viable: requires 1 argument, but 2 were provided
S(T..., int);
^
Run Code Online (Sandbox Code Playgroud)
在我看来,这应该工作,T应该被推断为一个长度为1的包.
如果标准禁止做这样的事情,有谁知道为什么?
C++标准第8.3.6.4节说明了这一点
对于非模板函数,可以在稍后的同一范围内的函数声明中添加默认参数.[...]
但我的问题是,为什么它不允许模板功能?不允许在模板函数的同一范围内的后续声明中添加默认参数的基本原理是什么?
考虑这个编译好的程序.(非模板功能)(请参阅此处的现场演示.)
#include <iostream>
int f(int a,int b,int c=3);
int f(int a,int b=9,int c); // default argument in middle, ok allowed
int main()
{
f(3);
f(3,6);
f(3,6,9);
return 0;
}
int f(int a,int b,int c)
{
std::cout<<a<<' '<<b<<' '<<c<<'\n';
return 0;
}
Run Code Online (Sandbox Code Playgroud)
#include <iostream>
template <typename T>
void f(T a,int b,int c=3);
template <typename T>
void f(T a,int b=9,int c); // compiler error why???
int main()
{
f(3);
f(3,6); …Run Code Online (Sandbox Code Playgroud) c++ templates language-lawyer function-templates default-arguments
我试图找出模板化函数的部分规范是否是C++标准的一部分,或者这是否是编译器特定的.
通过部分规范,我的意思是仅指定编译器无法推断的类型.所以,如果我有一个模板函数'f',它有三种类型,一个在参数中使用并且可以推导出来,我可以用表格调用'f'f<type, type>(parameter)
这是一个例子:
#include <iostream>
#include <tuple>
#include <string>
template<class A, class B, class C>
std::tuple<A, B> test(C c)
{
// do something based on c, return tuple with types A and B
return std::make_tuple(A(), B());
}
int main(void)
{
// I expected I would have to use this form. Specify all parameters.
std::tuple<int, int> value3 = test<int, int, int>(5);
// Here, I only specified the return value types, did not specify the parameter type, yet it compiles. …Run Code Online (Sandbox Code Playgroud) c++ templates function-templates template-argument-deduction
添加了 C++20 std::to_array,因此您可以轻松地从 C 样式数组创建std::array,例如:
template<typename T, std::size_t N>
void foo(const T (&a)[N]) {
auto arr = std::to_array(a);
}
Run Code Online (Sandbox Code Playgroud)
但是,std::to_array不支持二维数组,因此以下方法不起作用:
auto arr = to_array({1, 2}, {3, 4});
Run Code Online (Sandbox Code Playgroud)
这可以手动实现吗?
是否可以使用(boost)bind将参数绑定到函数模板?
// Define a template function (just a silly example)
template<typename ARG1, typename ARG2>
ARG1 FCall2Templ(ARG1 arg1, ARG2 arg2)
{
return arg1 + arg2;
}
// try to bind this template function (and call it)
...
boost::bind(FCall2Templ<int, int>, 42, 56)(); // This works
boost::bind(FCall2Templ, 42, 56)(); // This emits 5 pages of error messages on VS2005
// beginning with: error C2780:
// 'boost::_bi::bind_t<_bi::dm_result<MT::* ,A1>::type,boost::_mfi::dm<M,T>,_bi::list_av_1<A1>::type>
// boost::bind(M T::* ,A1)' : expects 2 arguments - 3 provided
boost::bind<int>(FCall2Templ, …Run Code Online (Sandbox Code Playgroud) 请考虑以下代码,该代码使用带有可变参数的函数:
#include <iostream>
// Typedef function type
template<typename... Output>
using Func = void(Output*...);
// Function runner
template<typename... Output>
void run_func(Func<Output...>& func, Output*... output) {
for (int i=0 ; i < 10 ; ++i) {
func(output...);
}
}
void f(double* d) {
*d *= 2;
};
int main() {
double value = 1.0;
run_func(f, &value);
printf("%f\n", value);
}
Run Code Online (Sandbox Code Playgroud)
用g ++ 4.7.3编译它可以正常工作,并且运行1024.0按预期生成.
使用icpc 14.0.2进行编译会使其崩溃...
templ.cc(21): internal error: assertion failed: lower_expr: bad kind (shared/cfe/edgcpfe/lower_il.c, line 18582)
run_func(f, &value);
^
Run Code Online (Sandbox Code Playgroud)
使用clang 3.5.0-1进行编译会出现以下错误消息: …
这是代码:
struct foo {
template<typename T = void>
friend foo f() { return {}; }
};
int main() {
auto x = f(); // clang++ can't find it, g++ can.
}
Run Code Online (Sandbox Code Playgroud)
clang ++ 3.4给出:
fni2.cpp:8:12: error: use of undeclared identifier 'f'
auto x = f(); // clang++ can't find it, g++ can.
^
1 error generated.
Run Code Online (Sandbox Code Playgroud)
g ++ 4.9.0编译它,但我不认为它应该有.这是一个相关的问题,但没有明确的答案.第15.4.2/2,4节讨论了这一点,但他们都没有说任何暗示在类中定义的友元函数模板应该与类中定义的非模板友元函数具有不同的可见性.
这只是我的学术兴趣,虽然它确实来自其他可能有实际用例的人提出的问题.
它看起来像是一个g ++错误.
#include <iostream>
using namespace std;
template <class X, class Y>
Y big(X a, Y b)
{
if (a > b)
return (a);
else return (b);
}
int main()
{
cout << big(32.8, 9);
}
Run Code Online (Sandbox Code Playgroud)
在这里,我在 CPP 中使用模板,所以当我调用函数big绕过参数double和int类型时,我想要返回答案是double. 这里的类型,它返回32而不是32.8.
我如何获得我想要的输出?如何编写正确的big函数返回类型?
c++ ×10
templates ×7
c++11 ×3
algorithm ×1
boost ×1
boost-bind ×1
c++20 ×1
clang ×1
friend ×1
function ×1
name-lookup ×1
return-type ×1
stdarray ×1