标签: function-templates

如何编写可以接受堆栈或队列的函数模板?

我采取四种算法是完全不同的,因为他们使用什么数据结构相同-两个用priority_queue,一个用途stack,最后的用途queue.它们相对较长,所以我想只有一个函数模板接受容器类型作为模板参数,然后让每个算法用适当的参数调用该模板,如下所示:

template <class Container>
void foo(/* args */)
{
    Container dataStructure;
    // Algorithm goes here
}

void queueBased(/* args */)
{
    foo<queue<Item> >(/* args */);
}

void stackBased(/* args */)
{
    foo<stack<Item> >(/* args */);
}
Run Code Online (Sandbox Code Playgroud)

我已经成功地使用priority_queue- 和 - stack基础实现,但我不能对queue基于算法的算法做同样的事情,因为它使用不同的名称来访问最重要的元素(front( )而不是top( )).我知道我可以专门针对这种情况使用模板,但后来我会有大量的重复代码(这是我要避免的).

实现这一目标的最佳方法是什么?我的第一个本能是为队列创建一个包装类,它添加了一个top( )等同于stack's 的操作,但我一直在读这个子类化STL类是一个禁忌.那我该怎么办呢?

c++ templates stl function-templates

5
推荐指数
1
解决办法
1335
查看次数

在C++ 11中,如何根据返回类型对一个函数对象进行专门化?

我在C++ 11中有一个包装函数,设计用于lambdas,如下所示:

template<typename Func>
int WrapExceptions(Func&& f)
{
  try
  {
    return f();
  }
  catch(std::exception)
  {
    return -1;
  }
}
Run Code Online (Sandbox Code Playgroud)

我可以这样称呼它:

int rc = WrapExceptions([&]{
  DoSomething();
  return 0;
});
assert(rc == 0);
Run Code Online (Sandbox Code Playgroud)

生活还可以.但是,我想要做的是重载或专门化包装函数,这样当内部函数返回void时,外部函数返回默认值0,例如:

int rc = WrapExceptions([&]{
  DoSomething();
});
assert(rc == 0);
Run Code Online (Sandbox Code Playgroud)

我可以在C++ 11中实际执行此操作吗?我不能为我的生活思考如何.

c++ templates function-templates c++11

5
推荐指数
1
解决办法
380
查看次数

根据其他模板参数指定返回类型

我想通过其他模板参数指定模板化函数的返回类型。所有这些都在一个班级中。

在头文件中:

class MyClass {
    template<int type, typename RT>
    RT myfunc();
};
Run Code Online (Sandbox Code Playgroud)

在 .cpp 中是这样的:

template<>
int MyClass::myfunc<1, int>() { return 2; }

template<>
double MyClass::myfunc<2, double>() { return 3.14; }

template<>
const char* MyClass::myfunc<3, const char*>() { return "some string"; }
Run Code Online (Sandbox Code Playgroud)

我希望能够像这样使用我的功能:

MyClass m;
int i = m.myfunc<1>(); // i will be 2
double pi = m.myfunc<2>(); // pi will be 3.14
const char* str = m.myfunc<3>(); // str == "some string"
Run Code Online (Sandbox Code Playgroud)

所以我希望我的函数能够通过一个模板整数(或任何枚举)进行参数化,并且基于这个整数,返回类型会有所不同。我不希望该函数使用指定参数以外的任何其他整数参数,例如这里m.myfunc<4>()会产生编译错误。

我只想通过一个模板参数来参数化我的函数,因为它m.myfunc<1, int>()可以工作,但我不想一直写类型名。 …

c++ templates return-type function-templates

5
推荐指数
1
解决办法
1588
查看次数

基于嵌套类型的模板函数选择

以下代码在VS2015上正常工作:

struct Foo
{
   using Bar = int;
   auto operator()() { return "Foo!";  }
};

template <typename Callable, typename CodeType> // <<< CodeType is a template param
void funky(CodeType code, Callable func)
{
   cout << "Generic: " << code << ", " << func() << endl;
}

template <typename HasBar>
void funky(typename HasBar::Bar code, HasBar func) // <<< The code type is a nested type
{
   cout << "Has Bar: " << code << ", " << func() << endl; …
Run Code Online (Sandbox Code Playgroud)

c++ gcc clang function-templates visual-studio-2015

5
推荐指数
1
解决办法
159
查看次数

合法使用非跟踪功能模板参数包?

在调试某人讨厌的宏生成的代码时,我看到仅MSVC ++对类似于以下函数模板声明的内容不满意:

template <typename ...Vs, typename>
void foo();
Run Code Online (Sandbox Code Playgroud)

很公平。我对为什么GCC和Clang会编译它感到困惑。我foo在上面的声明中添加了的定义,现在GCC也产生了编译错误(Clang仍然存在)。此代码如下:

template <typename ...Vs, typename>
void foo();

template <typename ...Vs, typename = int>
void foo() {  }

int main(int argc, char *argv[])
{
  foo<char,float>();
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

Clang是对还是错?我注意到,如果删除了声明,则GCC和MSVC ++可以编译。

c++ function-templates default-parameters variadic-templates c++11

5
推荐指数
1
解决办法
84
查看次数

constexpr 函数仅在声明为看似无关的模板时才有效

以下代码无法编译;g++ 7.3.0 with--std=c++17给出了错误信息

constexpr 函数 'constexpr const C operator+(const C&, int)' 的无效返回类型 'const C'
注意:'C' 不是文字,因为 'C' 有一个非平凡的析构函数

#include <string>

using namespace std ;

struct C
  {
  C (std::string s) : s (s) { }
  std::string s ;
  } ;

constexpr const C operator+ (const C& x, int y) // <-- Error here
  {
  return C ("C int") ;
  }

int main()
  {
  C c ("abc") ;
  printf ("%s\n", (c + 99).s.c_str()) ;
  }
Run Code Online (Sandbox Code Playgroud)

好吧,好吧。但是如果我添加一个看似无关的模板规范到operator+

template<typename …
Run Code Online (Sandbox Code Playgroud)

c++ function-templates c++17 constexpr-function

5
推荐指数
0
解决办法
64
查看次数

“用作非类型模板参数”是否使函数模板隐式实例化?

我想编写一个M接受不完整类型C作为模板参数的类模板。但我也希望C在最终定义时具有一些特征。

此代码是否有保证

  • 编译如果定义(标志),
  • 如果 !defined(FLAG) 编译失败?
template <auto> struct Dummy {};

template <typename C>
void check()
{
    static_assert(std::is_trivial_v<C>);
}

template <typename C>
struct M : Dummy<&check<C>>
{
    //static_assert(std::is_trivial_v<C>);//error: incomplete type
    C * p;
};

struct Test;
M<Test> m;

int main()
{
    return 0;
}

#if defined(FLAG)
struct Test {};
#else
struct Test { std::string non_trivial_member; };
#endif
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer function-templates implicit-instantiation non-type-template-parameter

5
推荐指数
1
解决办法
77
查看次数

如何删除这种重复(对于循环类型)?

我有这样的代码:

template<class Command>
void registerCmd() {
    Command x{};
    // do something with x...
}

namespace Cmd
{
    struct GET { /* some methods */ };
    struct GETSET { /* some methods */ };
    struct DEL { /* some methods */ };

    void registerCommands() {
        registerCmd<GET>();
        registerCmd<GETSET>();
        registerCmd<DEL>();
    }
}
Run Code Online (Sandbox Code Playgroud)

我喜欢代码的结果。我想知道是否有办法将此代码更改为如下所示:

namespace Cmd 
{
    void register() {
        // this does not compile
        for (TYPE in{ GET, GETSET, DEL })
            registerCmd<TYPE>();
    }
}
Run Code Online (Sandbox Code Playgroud)

可以使用可变参数模板吗?

c++ templates function-templates variadic-templates c++17

5
推荐指数
1
解决办法
71
查看次数

函数模板重载解析期间的 MSVC 与 Clang/GCC 错误,其中一个函数模板包含参数包

当我使用参数包时,我注意到这样一种情况(如下所示)在 gcc 和 clang 中编译得很好,但在 msvc 中却不行:

template<class T> void func(T a, T b= T{})
{
    
}
template<class T, class... S> void func(T a, S... b)
{

}
 
int main()
{
    func(1); // Should this call succeed? 
}
Run Code Online (Sandbox Code Playgroud)

这是验证相同内容的链接:https://godbolt.org/z/8KsrcnMez

可以看到,上面的程序在 msvc 中失败,并显示错误消息:

<source>(13): error C2668: 'func': ambiguous call to overloaded function
<source>(6): note: could be 'void func<int,>(T)'
        with
        [
            T=int
        ]
<source>(2): note: or       'void func<int>(T,T)'
        with
        [
            T=int
        ]
<source>(13): note: while trying to match the argument list …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer function-templates pack-expansion parameter-pack

5
推荐指数
1
解决办法
226
查看次数

可变参数模板函数对非可变参数的特殊化

我有一个函数模板,该函数至少接受一个参数并对其余参数执行一些格式化:

template <typename T, typename... ARGS>
void foo(T first, ARGS&&... args)
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

当第一个参数是特定类型时,我希望它做不同的事情。我喜欢编译器选择这个特定的版本,其中其余的可变参数被忽略。所以我尝试了模板专业化:

template <>
void foo(const ICON* p)
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

或者:

template <typename T, typename... ARGS>
void foo(const ICON* p, ARGS&&... args)
{
   // ...
}
Run Code Online (Sandbox Code Playgroud)

我还尝试了非模板化重载,但它总是选择第一个版本。

调用者代码应该根本不知道模板(遗留代码、向后兼容性废话等),因此它依赖于类型推导和如下调用:

MyClass fooMaker;
fooMaker.set("A", "B", 3.14, 42); // v1
fooMaker.set(pIcon);              // v2 (special)
Run Code Online (Sandbox Code Playgroud)

c++ templates function-templates overload-resolution variadic-templates

5
推荐指数
1
解决办法
230
查看次数