我试图了解模板专业化是如何工作的。我有以下功能模板:
template <typename T>
void function(const T &t1, const T &t2)
{
std::cout << "in function template: " << t1 << ", " << t2 << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
现在,我想专门化这个函数模板,以防它被一个指向 const 的指针调用:
// template specialization
template <>
void function(const char *&t1, const char *&t2)
{
std::cout << "in compare template specialization: " << t1 << ", " << t2 << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
但是编译器抱怨它找不到专门化的函数模板:
In file included from main.cpp:1:0:
template.h:23:5: error: template-id 'compare<>' for 'int compare(const char*&, const char*&)' does not match …Run Code Online (Sandbox Code Playgroud) 我试图在两个不同的类上建立接口,其中函数的实现位于子类中。它适用于常规函数,但不幸的是不适用于模板函数。
参见示例:
import std.conv;
import std.stdio;
interface Num {
T num(T)();
}
class A : Num {
T num(T)() {
return 5.to!T;
}
}
class B : Num {
T num(T)() {
return 2.to!T;
}
}
void main() {
auto a = new A();
auto b = new B();
Num somea = a;
Num someb = b;
writeln(a.num!int());
writeln(somea.num!int());
writeln(someb.num!int());
writeln(somea.num!string());
writeln(someb.num!string());
}
Run Code Online (Sandbox Code Playgroud)
(也可以在线获取: https: //run.dlang.io/is/Nl1edV)
结果是一个错误:
onlineapp.d:26: error: undefined reference to '_D9onlineapp3Num__T3numTiZQhMFZi'
onlineapp.d:27: error: undefined reference to '_D9onlineapp3Num__T3numTiZQhMFZi' …Run Code Online (Sandbox Code Playgroud) 我希望我的函数采用左值引用,而绝对不是右值或临时值或其他任何值。
这是我的功能:
template<class T>
void foo(T& value) {}
// Imagine I have a class Foo
struct Foo
{
int a;
int b;
};
Run Code Online (Sandbox Code Playgroud)
当我调用 时foo(Foo{1, 2}),首先,即使我要求左值引用,它也会编译,其次,它不起作用,因为foo存储了传递值的地址,所以我稍后阅读时会得到垃圾。
如何强制foo采用左值引用?
假设我下面有两个函数,在Foo()函数中,我如何将hw字符串打包到 args 并将它们转发到Bar()?
我试过了,std::bind但这没有用。
template<typename T, typename... Args>
void Bar(Args&&... args)
{
// do something with args
}
template<typename T, typename... Args>
void Foo(Args&&... args)
{
if (typeid(T) == typeid(std::string)) {
std::string hw = "Hello, world!";
Bar<T>(std::forward<Args>(hw, args)...); // how to add hw to the forward list?
}
else {
Bar<T>(std::forward<Args>(args)...);
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:终于我找到了我的错误!对于那些你谁是想知道为什么hw不转移到Bar()即使你这样做是正确的,请讲究Bar()的else分支。如果Bar()期望不同类型的参数取决于T并且代码不会编译,则else分支可能会发出编译器错误。正如@JeJo 提到的,我应该使用它if constexpr …
我试图弄清楚 sfinae 概念在 C++ 中是如何工作的。但我无法说服对象类型编译器 if boolis trueor false。
#include <iostream>
class A {
public:
void foo() { std::cout << "a\n"; }
};
class B {
public:
void ioo() { std::cout << "b\n"; }
};
template<class T>
void f(const T& ob, bool value = false)
{
if constexpr (!value) ob.foo();
else ob.ioo();
}
int main()
{
A ob1;
B ob2;
f(ob1, true);
f(ob2, false);
}
Run Code Online (Sandbox Code Playgroud) gcc 11.2 似乎无法编译这个:
template <typename T = int>
struct Test {};
template <typename T> void foo(T& bar) {}
int main()
{
Test t;
foo<Test>(t);
}
Run Code Online (Sandbox Code Playgroud)
但没有问题
template <typename T = int>
struct Test {};
template <typename T> void foo(T& bar) {}
int main()
{
Test t;
foo<Test<>>(t);
}
Run Code Online (Sandbox Code Playgroud)
这是编译器错误吗?
这个问题似乎表明它应该有效。
这是一个最小的代码示例,展示了我正在尝试的工作原理,但不是我希望的工作方式:
#include <string>
#include <type_traits>
#include <iostream>
struct string_tag {
using R=const std::string;
};
struct int_tag {
using R=const int;
};
template <bool TS>
class Wibble {
public:
template<typename TAG>
typename TAG::R getValue(TAG);
};
template <bool TS>
template <typename TAG>
typename TAG::R Wibble<TS>::getValue(TAG) {
if constexpr (std::is_same<TAG, string_tag>::value) {
return "hello";
}
if constexpr (std::is_same<TAG, int_tag>::value) {
return 42;
}
}
// instantiate classes
template class Wibble<true>;
template class Wibble<false>;
int main () {
Wibble<true> tw;
Wibble<false> fw;
std::cout << …Run Code Online (Sandbox Code Playgroud) c++ templates specialization template-specialization function-templates
给定一个函数print<size_t>(void)和 a ,我想要一个调用每个inconstexpr std::array<size_t,3> q={1,2,3}的循环。print<qi>qiq
我的最小示例如下所示:
#include<iostream>
#include<array>
template<size_t n>
void print(){ std::cout << n << "\n"; }
template< size_t N, const std::array<const size_t,N> q>
constexpr void print_long(){
//
// I) this is what I want to do
for(size_t i=0;i<N;++i){ print<q[i]>(); }
//
// II) this does not compile either (because "it++")
constexpr auto it = q.begin();
while(it!=q.end()){ print<*(it++)>(); }
//
// III) for_each is no constexpr either
std::for_each(q.begin(),q.end(),[](const auto& it){ print<it>(); }); …Run Code Online (Sandbox Code Playgroud) 在c ++中使用类T的一个优点是减少在函数中重新定义数据类型的时间,如果这些数据类型在其他函数中定义,例如在int main中.
template <class T>
void showabs(T number)
{
if (number < 0 )
number = -number;
cout << number << endl;
return 0;
}
int main()
{
int num1 = -4;
float num2 = -4.23f;
showabs(num1);
showabs(num2);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
所以在这种情况下,没有类T,对于每种数据类型,我们必须添加其相应的数据类型条件,即另一组if语句用于int,另一组用于float.
我对么?
考虑以下代码:
template<typename T>
class Base
{
template<typename U>
friend void f(void *ptr) {
static_cast<Base<U>*>(ptr)->run();
}
protected:
virtual void run() = 0;
};
class A : public Base<A>
{
protected:
virtual void run() {}
};
/*
class B : public Base<B>
{
protected:
virtual void run() {}
};
*/
Run Code Online (Sandbox Code Playgroud)
现在可以编译良好(ideone)。但是,如果我取消注释的定义B,那么它将给出以下错误(ideone):
prog.cpp: In instantiation of ‘Base<B>’:
prog.cpp:20: instantiated from here
prog.cpp:6: error: redefinition of ‘template<class U> void f(void*)’
prog.cpp:6: error: ‘template<class U> void f(void*)’ previously defined …Run Code Online (Sandbox Code Playgroud)