我听说C++类成员函数模板不能是虚拟的.这是真的?
如果它们可以是虚拟的,那么一个人可以使用这样一个函数的场景的例子是什么?
我知道语言规范禁止功能模板的部分特化.
我想知道为什么禁止它的理由?它们没用吗?
template<typename T, typename U> void f() {} //allowed!
template<> void f<int, char>() {} //allowed!
template<typename T> void f<char, T>() {} //not allowed!
template<typename T> void f<T, int>() {} //not allowed!
Run Code Online (Sandbox Code Playgroud) c++ language-design partial-specialization template-specialization function-templates
template<typename T>
void f(T a, const T& b)
{
++a; // ok
++b; // also ok!
}
template<typename T>
void g(T n)
{
f<T>(n, n);
}
int main()
{
int n{};
g<int&>(n);
}
Run Code Online (Sandbox Code Playgroud)
请注意:b是的const T&,++b没关系!
为什么const T&不确定是const?
考虑
#include <iostream>
#include <type_traits>
template <class T, class ARG_T = T&>
T foo(ARG_T v){
return std::is_reference<decltype(v)>::value;
}
int main() {
int a = 1;
std::cout << foo<int>(a) << '\n';
std::cout << foo<int, int&>(a) << '\n';
}
Run Code Online (Sandbox Code Playgroud)
我希望两种情况下的输出均为1。但在第一种情况下为0:与默认值class ARG_T = T而不是一致class ARG_T = T&。
我想念什么?
c++ templates function-templates template-argument-deduction argument-deduction
#include <iostream>
struct uct
{
uct() { std::cerr << "default" << std::endl; }
uct(const uct &) { std::cerr << "copy" << std::endl; }
uct( uct&&) { std::cerr << "move" << std::endl; }
uct(const int &) { std::cerr << "int" << std::endl; }
uct( int &&) { std::cerr << "int" << std::endl; }
template <typename T>
uct(T &&) { std::cerr << "template" << std::endl; }
};
int main()
{
uct u1 ; // default
uct u2( 5); // int
uct u3(u1); …Run Code Online (Sandbox Code Playgroud) c++ copy-constructor constructor-overloading function-templates overload-resolution
在下面的示例中,0它以一种特殊的方式运行:它选择与示例函数调用所期望的不同的重载。我想知道为什么。我的理解也如下。
#include <iostream>
template<typename T>
void f(T a) {
std::cout << "first" << std::endl;
}
template<typename T>
void f(T* a) {
std::cout << "second" << std::endl;
}
int main()
{
f(0);
f<size_t>(0);
f<size_t>(0UL);
f(1);
f<size_t>(1);
}
Run Code Online (Sandbox Code Playgroud)
输出:
first
second
first
first
first
Run Code Online (Sandbox Code Playgroud)
我的理解:
f(0)- 模板参数推导,整数文字0是int类型,因此f选择第一个T=int
f<size_t>(0)-带有整数提升的显式模板实例化,选择的类型是T=size_t,选择第一个函数并从到提升0(我在这里错了)intsize_t
f<size_t>(0UL)- 与上面相同,但没有升级(0 已经是 type size_t)
f(1)- 与 …
c++ templates function-templates overload-resolution template-argument-deduction
假设我有一个template功能:
template<typename T>
T produce_5_function() { return T(5); }
Run Code Online (Sandbox Code Playgroud)
我怎么能将这整个传递template给另一个template?
如果produce_5_function是仿函数,那就没有问题:
template<typename T>
struct produce_5_functor {
T operator()() const { return T(5); }
};
template<template<typename T>class F>
struct client_template {
int operator()() const { return F<int>()(); }
};
int five = client_template< produce_5_functor >()();
Run Code Online (Sandbox Code Playgroud)
但我希望能够使用原始函数模板执行此操作:
template<??? F>
struct client_template {
int operator()() const { return F<int>(); }
};
int five = client_template< produce_5_function >()();
Run Code Online (Sandbox Code Playgroud)
我怀疑答案是"你不能这样做".
来自cppreference.com的报价:
添加模板特化
允许为任何标准库类添加模板特化(从C++ 20开始)| 模板到命名空间std只有当声明依赖于至少一个程序定义的类型并且特化满足原始模板的所有要求时,除非禁止这样的特化.
是否意味着,从C++ 20开始,将std不再允许将函数模板的特化添加到用户定义类型的命名空间中?如果是这样,它意味着许多现有代码可能会破坏,不是吗?(在我看来,这是一种"激进"的改变.)此外,它会向这些代码注入未定义的行为,这不会触发编译错误(警告有希望).
在阅读另一个问题时,我遇到了部分排序问题,我将其缩减为以下测试用例
template<typename T>
struct Const { typedef void type; };
template<typename T>
void f(T, typename Const<T>::type*) { cout << "Const"; } // T1
template<typename T>
void f(T, void*) { cout << "void*"; } // T2
int main() {
// GCC chokes on f(0, 0) (not being able to match against T1)
void *p = 0;
f(0, p);
}
Run Code Online (Sandbox Code Playgroud)
对于两个函数模板,进入重载分辨率的特化的函数类型是void(int, void*).但是,部分排序(根据comeau和GCC)现在说第二个模板更专业.但为什么?
让我通过部分排序,并显示我有问题的地方.可以Q被用于确定根据偏序的独特由上型14.5.5.2.
T1(Q插入)(Q, typename Const<Q>::type*).参数的类型是AT=(Q, void*)T2 …c++ templates partial-ordering function-templates template-argument-deduction
似乎c#不支持类似c ++的模板.例如
template <class myType>
myType GetMax (myType a, myType b) {
return (a>b?a:b);
}
Run Code Online (Sandbox Code Playgroud)
我希望我的函数有基于其参数的返回类型,我如何在c#中实现这一点?如何在C#中使用模板
编辑:我可以使用object和getType几乎相同的目的?