我有这个代码:
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
如果我有一个默认模板类型的模板类,但我必须写模板尖括号.有可能避免这种情况吗?
例:
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_.有没有其他解决方案,我还没有看到.
我有以下课程:
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不是允许的默认参数?
根据
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 *> …
为什么当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)
我的问题
priority_queue一个vector?这是什么意思,什么时候需要指定第二个参数?decltype需要这个 lambda?leaderBoard需要初始化(myComp)A.second …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++ 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++.我想我的不确定性可能来自<>使用默认模板创建模板化类的实例时使用空尖括号的要求,如下所述:
但我认为在我的情况下,功能括号()是关键区别?
我必须在这里遗漏一些明显的东西,因为这真的让我惊讶.
以下代码给出了错误: error: missing template arguments before ‘a’
template<int n=0>
class A {};
...
A a;
...
Run Code Online (Sandbox Code Playgroud)
是否有必要实例化为具有默认值声明的1参数的模板指定其值?
有人引用标准吗?
我可以在不破坏用户代码的情况下将类转换为模板类吗?我正在尝试更改一个类以接受模板参数,但同时,我想避免破坏现有的客户端代码。更详细地说,现有的代码库是
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)
我很感激任何提示或建议!