相关疑难解决方法(0)

默认模板参数:为什么编译器会抱怨没有指定模板参数?

我有这个代码:

struct A{};

template<class T = A>
struct B {
    void foo() {}
};

B b; //Error: missing template arguments before 'b'
     //Error: expected ';' before 'b'
     //More errors
b.foo()
Run Code Online (Sandbox Code Playgroud)

如果我foo()使用相同的模板'signature'作为模板函数,编译器不会抱怨没有指定模板参数:

struct A {};

struct B {
    template<class T = A>
    void foo() {}
};

B b; //OK
b.foo()
Run Code Online (Sandbox Code Playgroud)

那么为什么我需要为带有默认参数的模板类指定参数,而不是为模板函数指定?我遗失了一些微妙之处吗?

原因是因为模板参数推断失败肯定.但我想知道原因.

c++ templates default-parameters template-argument-deduction

8
推荐指数
1
解决办法
2336
查看次数

避免默认模板中的尖括号

如果我有一个默认模板类型的模板类,但我必须写模板尖括号.有可能避免这种情况吗?

例:

template <typename T=int>
class tt {
public:
  T get() { return 5; }
};

...

tt<> t;  // how to avoid <>
std::cout << t.get() << std::endl;
Run Code Online (Sandbox Code Playgroud)

到目前为止,我已通过单独的命名空间完成此操作并重新声明该类:

namespace detail_ {
template <typename T=int>
class tt {
public:
  T get() { return 5; }
};
}

class tt : public detail_::tt {}

...

tt t;
std::cout << t.get() << std::endl;
Run Code Online (Sandbox Code Playgroud)

问题是,如果我想使用其他类型的类,我必须去名称空间detail_.有没有其他解决方案,我还没有看到.

c++ templates coding-style class-template

8
推荐指数
3
解决办法
1871
查看次数

为什么不允许使用此默认模板参数?

我有以下课程:

template <typename Type = void>
class AlignedMemory {
public:
    AlignedMemory(size_t alignment, size_t size)
        :   memptr_(0) {
        int iret(posix_memalign((void **)&memptr_, alignment, size));
        if (iret) throw system_error("posix_memalign");
    }
    virtual ~AlignedMemory() {
        free(memptr_);
    }
    operator Type *() const { return memptr_; }
    Type *operator->() const { return memptr_; }
    //operator Type &() { return *memptr_; }
    //Type &operator[](size_t index) const;
private:
    Type *memptr_;
};
Run Code Online (Sandbox Code Playgroud)

并尝试实例化一个自动变量,如下所示:

AlignedMemory blah(512, 512);
Run Code Online (Sandbox Code Playgroud)

这会出现以下错误:

src/cpfs/entry.cpp:438:错误:'blah'之前缺少模板参数

我究竟做错了什么?是void不是允许的默认参数?

c++ templates g++ default-parameters

6
推荐指数
2
解决办法
2312
查看次数

C++中类模板的模板参数推导17:我做错了吗?

根据 https://gcc.gnu.org/projects/cxx-status.html,g ++版本7与flag一起使用-std=c++1z,支持类模板的模板参数推导.

我希望编译以下代码,特别是作为Base一个抽象类,因此:
1.编译器知道没有Base可以创建的实例;
2.指向base的指针指向pt_base一个明确定义的实例(即Derived<int>{42}),其中type(int)是显式的.

template<typename ValueType>
class Base {
public:
    virtual ValueType getValue() = 0;
};

template<typename ValueType>
class Derived : public Base<ValueType>{
public:
    Derived(ValueType argt){ value = argt; }
    virtual ValueType getValue(){ return value; }
    ValueType value;
};

int main(){
    Base *pt_base = new(Derived<int>{42}); // *ERROR*
    delete pt_base;
}
Run Code Online (Sandbox Code Playgroud)

然而,它没有编译.G ++抱怨" 模板占位符类型'Base'必须后跟一个简单的declarator-id "; 如果我理解正确,它不会推断出模板参数.
遗憾是因为我想动态决定哪个派生类pt_base指向(可能是来自类Derived<someType>或类的对象Derived2<someType2>).这样,一个数组或一个vector<Base *> …

c++ templates g++ c++17

4
推荐指数
1
解决办法
1463
查看次数

为什么 Vector 被用作 Priority Queue 的第二个参数?

为什么当priority_queue与单个数据类型使用,就像“诠释”,我们初始化像这样:priority_queue<int>; 但是,当它用一对初始化时,我们添加了向量类型的第二个参数priority_queue<pair<int,int>, vector<pair<int,int>>>

另外,我注意到有几种方法可以添加指定排序的第三个参数。

方法 1 - 结构

struct myCompare {
   bool operator()(const pair<int, int>& A, const pair<int, int>& B) {
       return A.second < B.second;
   }
};

priority_queue<pair<int, int>, vector<pair<int, int>>, myCompare> leaderBoard;

Run Code Online (Sandbox Code Playgroud)

方法 2 - Lambda

auto myComp = [](const pair<int, int>& A, const pair<int, int>& B) 
              {return A.second < B.second;};

priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(myComp)> leaderBoard(myComp);
Run Code Online (Sandbox Code Playgroud)

我的问题

  1. 为什么是第二个参数priority_queue一个vector?这是什么意思,什么时候需要指定第二个参数?
  2. 在方法 2 中,为什么decltype需要这个 lambda?
  3. 方法二中,为什么对象leaderBoard需要初始化(myComp)
  4. 在方法2中,为什么不能直接将我的lambda指定为第三个参数?
  5. A.second …

c++ lambda vector priority-queue decltype

3
推荐指数
1
解决办法
658
查看次数

模板函数中的默认模板需要空尖括号 &lt;&gt;

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)

这是编译器错误吗?

这个问题似乎表明它应该有效。

c++ templates function-templates default-template-argument

3
推荐指数
1
解决办法
377
查看次数

没有尖括号可以调用模板化功能吗?

关于在C++ 11中调用模板化函数需要什么,我有点困惑,其中为模板参数提供了默认值.

例如,假设我有以下模板化函数

template <class T = double> void foo()
{
  /* Do something */
}
Run Code Online (Sandbox Code Playgroud)

我想在我的代码中的某个地方调用它.所有这些有效的电话都是?

foo(); //Is this OK?
foo<>();
foo<int>();
Run Code Online (Sandbox Code Playgroud)

它与GCC 4.7.2编译得很好,但我不确定它是否是严格正确的C++.我想我的不确定性可能来自<>使用默认模板创建模板化类的实例时使用空尖括号的要求,如下所述:

模板默认参数

但我认为在我的情况下,功能括号()是关键区别?

templates c++11

2
推荐指数
1
解决办法
876
查看次数

具有一个参数和默认值的类模板

我必须在这里遗漏一些明显的东西,因为这真的让我惊讶.

以下代码给出了错误: error: missing template arguments before ‘a’

template<int n=0>
class A {};

...
A a;
...
Run Code Online (Sandbox Code Playgroud)

是否有必要实例化为具有默认值声明的1参数的模板指定其值?

有人引用标准吗?

c++ templates

2
推荐指数
1
解决办法
379
查看次数

如何在不破坏现有客户端代码的情况下将类转换为模板类(c++17 之前)?

我可以在不破坏用户代码的情况下将类转换为模板类吗?我正在尝试更改一个类以接受模板参数,但同时,我想避免破坏现有的客户端代码。更详细地说,现有的代码库是

class A{ // some code };
Run Code Online (Sandbox Code Playgroud)

我把它变成了以下内容:

template <type T = defaultType>
class A{ // some code };
Run Code Online (Sandbox Code Playgroud)

非模板化代码是为defaultType. 我可以做任何事情以使现有代码在没有 c++17(或更高版本)支持的情况下编译时不会中断吗?例如,以下内容应该是有效的:

A a{}; //existing code; works under c++17 with CTAD. How to use in c++14?
A<typeFoo> b{} //new code, if users decide to use a different template argument;
Run Code Online (Sandbox Code Playgroud)

我很感激任何提示或建议!

c++ templates c++11 c++14

2
推荐指数
1
解决办法
51
查看次数